難得有機會向老婆炫耀 linux 的厲害: 她想要把 DVD 備份成 mp4, 結果以前買的軟體已下架, 而 windows 又拒絕用檔案總管去開啟 DVD。 在 linux 底下, 看到的不過就是一個檔案系統, 備份、 播放當然都沒問題, 其實也並不需要轉檔啊。 那順便來研究一下 VIDEO_TS/ 底下的 VTS_*.VOB 好了, 特別是老婆交代的「字幕」部分。 我看到的大部分 DVD 都只有一個字幕軌, 只有一部 「史瑞克」 有多種語言。 那就拿其中一個較短, 又含字幕的影片檔 VTS_03_1.VOB 來實驗好了:
VOB_FILE=VTS_03_1.VOB BASE_NAME=${VOB_FILE%.VOB} echo $BASE_NAME
參考 這個 gist
的指令及範例輸出, 查看 VOB 檔案的基本資訊及所有軌的資訊:
ffprobe -v quiet -print_format json -show_format -show_streams $VOB_FILE > ${BASE_NAME}.json
再用 zq
把各軌資訊摘要成 csv 格式:
zq -f csv 'over streams | {index,codec_name,codec_tag_string}' ${BASE_NAME}.json
, 我看到的輸出是:
index,codec_name,codec_tag_string 0,dvd_nav_packet,[0][0][0][0] 1,mpeg2video,[0][0][0][0] 2,ac3,[0][0][0][0] 3,dvd_subtitle,[0][0][0][0] 4,dvd_subtitle,[0][0][0][0] 5,dvd_subtitle,[0][0][0][0]
所以 track 1 是影像軌, 2 是聲音 (只有一種語言的配音), 3、4、5 是三種語言的字幕, 可是沒記載各別是哪種語言。
ffmpeg -fflags genpts -i $VOB_FILE -map 0:1 -map 0:2 -codec:v copy -codec:a copy ${BASE_NAME}.mkv mencoder $VOB_FILE -nosound -ovc frameno -o /dev/null -vobsuboutindex 0 -sid 0 -vobsubout ${BASE_NAME}_zh_TW mencoder $VOB_FILE -nosound -ovc frameno -o /dev/null -vobsuboutindex 0 -sid 1 -vobsubout ${BASE_NAME}_th mencoder $VOB_FILE -nosound -ovc frameno -o /dev/null -vobsuboutindex 0 -sid 2 -vobsubout ${BASE_NAME}_zh_HK
接下來用 ffmpeg 指令把原始影片的影像軌 (0:1, 第 0 個輸入檔的第一軌) 跟聲音軌 (0:2) 抓出來變成 .mkv 檔, 又用 mencoder 把三個字幕軌抓出來, 分別命名為 VTS_03_1_zh_TW.*、 VTS_03_1_th.*、 VTS_03_1_zh_HK.*, 其中每種語言會產生 *.idx 跟 *.sub 兩個檔案。 選項 -sid 0 指的是第 0 個字幕軌, 也就是 ffprobe 查看原始影片所回報的第 3 軌。 語言名稱是事後看成果才知道該怎麼命名的; -sid 1 大概是泰文吧.. google 判斷的。
現在可以用 mplayer -vobsub ${BASE_NAME}_zh_TW ${BASE_NAME}.mkv
播放影片, 搭配台灣正體中文字幕。 用 -vobsub 指定字幕時,
不必寫副檔名, mplayer 會自動去找 .idx 跟 .sub 。
字幕顏色不清楚。 沒關係, 我們馬上把 「影音」 跟 「字幕」 合併起來:
mkvmerge -o ${BASE_NAME}_ALL.mkv ${BASE_NAME}.mkv *.idx *.sub
再查看一下新產生的 ${BASE_NAME}_ALL.mkv 的資訊:
ffprobe -v quiet -print_format json -show_format -show_streams ${BASE_NAME}_ALL.mkv > ${BASE_NAME}_mkv.json
以及 zq -f csv 'over streams | {index,codec_name,codec_tag_string}' ${BASE_NAME}_mkv.json
果然內含 0-4 影、音及三個字幕軌共五軌。
但是! 字幕軌的順序可能跟原來的不同,
可以用 vlc 播放並選不同的字幕軌來確認一下; 而且字幕顏色變正常囉!
既然已變成開放的 matroska (mkv) 影片格式,
當然也就可以用 ffmpeg 進一步做格式轉換等等其他處理。
但是! 來自 DVD 的字幕軌是圖片而不是文字,
所以沒有任何指令可以把它抓出來變成 .srt 字幕檔。
如果想轉成 .mp4 格式, 就必須選定一個 (圖片) 字幕軌,
把它 "壓" 進影像軌裡面:
ffmpeg -i ${BASE_NAME}_ALL.mkv -filter_complex "[0:v:0][0:s:2]overlay[vid]" -map [vid] -map 0:1 -codec:v libx264 -codec:a copy ${BASE_NAME}_zh_TW.mp4
(這裡的 0:s:2 選第二個字幕軌, 是根據剛剛在 vlc 裡面觀察的結果。)
產生的 ${BASE_NAME}_zh_TW.mp4 就只有影、音共兩軌,
而字幕是 "黏" 在影像軌裡面的。
這一題, linux 上的自由軟體的彈性再度大勝 windows 世界的專屬軟體!
(本篇的精華部分主要是從 這個問答 學來的。)
沒有留言:
張貼留言
因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。