使用了一陣子的 FFMpeg 處理影片,越用越喜歡這套軟體。
一開始,為了要將影片轉成 ipod touch 3代,可用的格式,特別學習
ffmpeg,試了好幾天,終於找出來滿意的方法,特此記錄下來,免得忘了。
轉檔時的指令
ffmpeg -i $1 -s 720x406 -vpre ipod -ac 2 -sn -y -vf subtitles=$1.srt $1.m4v
其中-i \$1 是要轉檔的檔名
-s 720x406 是轉檔後的解析度,406 = 720 * 720 /
1280,(原始檔的解析度為
1280x720)。這個一定要去計算,不然,在電視上看,畫面比例會不對,字幕可能出不來。
-vpre ipod 是為了 ipod 特別找出來的 preset,設定如後。
--ac 2 是轉成立體聲,不然 ipod touch 沒辦法播放。
--sn 不顯示原始檔中的字幕。因為,我要用另外的字幕檔。
--vf subtitles 為 srt 字幕檔。
preset設定
preset 可以放在 \~/.ffmpeg,檔名為 arg.ffpreset。例如,我設定了一個專門轉到 ipod touch 的 preset 檔,命名為
ipod.ffpreset。 :
strict=-2
vcodec=libx264
vprofile=main
level=30
maxrate=10000000
bufsize=10000000
preset=fast
#preset=slower
crf=20
#bf=0
#refs=1
#ab=192k
字幕
參考 How to burn subtitles into thevideo
原檔中已有圖片格式的字幕時,可直接燒錄:
-filter_complex '[0:v][0:s:1]overlay[v]' -map [v] -map 0:a
此處 -map 一定要下,不然會有錯誤訊息。 其中 -map 0:a是指所有的音軌,也可以直接指定音軌 -map 0:1
出現的訊息如下:
Stream mapping:
Stream #0:0 (h264) -> overlay:main (graph 0)
Stream #0:4 (pgssub) -> overlay:overlay (graph 0)
overlay (graph 0) -> Stream #0:0 (libx264)
加入外部字幕檔
1. 自行編輯字幕檔
這個很少用到,在 linux 中,就找到 aegisub是可用的,那就拿來用了,沒有什麼特別的考慮。
2. 提取 mkv 內 srt 或 ass 字幕
提取 mkv 內的文字字幕,用 :ffmpeg -i $1.mkv -vn -an -scodec copy $1.ssa
或:ffmpeg -i \$1.mkv -vn -an -scodec copy \$1.srt
有時會出現下列的錯誤訊息,內嵌的應該就是圖片格式字幕。 :Could not write header for output file #0 (incorrect codec parameters ?): Operation not permitted
爲了能改變字型大小,使用 ass 格式。3. srt
先轉成 ssa 檔,ffmpeg -i s.srt s.ssa
s.ssa 中加上; 同步字幕
Synch Point:0
; PlayResX/Y 影片解析度
PlayResX:720
PlayResY:480
; 調整字幕速度
Timer:100.0000
作出 ssa 檔後,可以用文字編輯器開啓,修改一下 fontname 和fontsize,讓字型美一點。 各參數用法見 ASS
字幕格式
如果不想控制字幕格式,就不須轉成 ass 格式,就用下列指令燒錄到影片。
-vf subtitles=sub.srt
4. 字幕轉成繁體
可以再用 opencc 把字幕轉成繁體:opencc -i $1.ssa -o o.ssa
5. ass
用 -vf 燒錄到影片中。-vf ass=s.ssa
或直接加入影片中,不是燒錄上去。 ffmpeg -i video.avi -i sub.ass -map 0:0 -map 0:2 -map 1 -c:a copy -c:v copy -c:s copy video.mkv
其中 video.avi 有一個視頻軌、兩個音頻軌,取其中的視頻軌 (mpa 0:0)和第二個音頻軌 (map 0:2) 加 sub.ass (map 1) 做成 video.mkv
而不重新編碼。
重點注意: -i sub.ass -map 1 -c:s copy。 此處的 sub.ass 也可以是
sub.srt。
合併多個影片
參考 How to concatenate (join, merge) mediafiles
mpeg:
ffmpeg -i "concat:input1.mpg|input2.mpg|input3.mpg" -c copy output.mpg
not mpeg:This is easiest to explain using an example::
ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex '[0:0] [0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]' \
-map '[v]' -map '[a]' <encoding options> output.mkv
On the -filter_complex line, the following:
'[0:0] [0:1] [1:0] [1:1]
tells ffmpeg what streams to send to the concat filter;
in this case, streams 0 and 1 from input 0 (input1.mp4 in this example),
and streams 0 and 1 from input 1 (input2.webm).
concat=n=2:v=1:a=1 [v] [a]'
This is the concat filter itself. n=2 is telling the filter that there are two input files;
v=1 is telling it that there will be one video stream;
a=1 is telling it that there will be one audio stream.
[v] and [a] are names for the output streams, to allow the rest of the ffmpeg line to use the output of the concat filter.
Note that the single quotes ' ' around the whole filter section are required.
-map '[v]' -map '[a]'
This tells ffmpeg to use the results of the concat filter rather than
the streams directly from the input files.
catflv
寫了個小小的 script,用來合併 flv,並轉成 ipod可用的 mp4。 :#!/bin/bash
icnt=0
for file in $@
do
filenames="$filenames -i $file "
scat="$scat[$icnt:0][$icnt:1]"
#echo $filenames, [$icnt], $scat
icnt=$(($icnt+1))
done
scmd="ffmpeg $filenames -filter_complex '$scat concat=n=$#:v=1:a=1 [v] [a]' -map '[v]' -map '[a]' -vpre ipod -ab 132k out.mp4"
echo $scmd
eval $scmd
DVD備份
DVD to ISO
爲了保存有價值的影片,儘量用比較高品質的壓縮方法。1. 參考:Encoding DVD into HQ flash video using
ffmpeg
將 DVD copy 成 ISO 檔,並掛上: :
$ dd if=/dev/cdrom of=dvd.iso
$ mkdir mnt
$ sudo mount dvd.iso mnt -o loop
$ ls -al mnt/
total 10
dr-xr-xr-x 4 4294967295 4294967295 136 2009-09-30 20:45 .
drwxr-xr-x 5 dpavlin dpavlin 4096 2009-10-15 22:01 ..
dr-xr-xr-x 2 4294967295 4294967295 40 2009-09-30 17:25 AUDIO_TS
dr-xr-xr-x 2 4294967295 4294967295 560 2009-09-30 18:45 VIDEO_TS
2. 或使用 dvdbackup,就不必再 mount dvd.iso,而且可以用 libdvdcss解除保護。
yaourt -S dvdbackup libdvdcss
dvdbackup -i /dev/cdrom -M -o ~/dvd_backup
DVD to MKV
先將 ISO 轉成 MKV :cat VTS_01_[1234].VOB | ffmpeg -i - -probesize 214748000 -analyzeduration 214748000 \
-map 0:0 -map 0:1 -map 0:2 \
-crf 18 -preset veryslow -tune help\
-filter:v yadif \
-c:a copy -c:s copy -y a.mkv
-probesize 214748000 -analyzeduration 214748000有時會因爲音軌或字幕軌太晚出現,ffmpeg
會偵測不到,這時就加長偵測的時間和大小。
-map 0:0 -map 0:1 -map 0:2 是要封裝到 mkv 的軌道。
-crf 18 -preset veryslow
用這個參數大概就好了,眼睛看不出來與原始有何差異。 有必要時可以再加上
-tune。
-filter:v yadif 就是 deinterlace。
-c:a copy -c:s copy 音軌和字幕軌都不重新編碼。
如果沒有字幕,可以先取得字幕檔,再保存到 mkv 中,如下: :
$ cat VTS_01_[1234].VOB | ffmpeg -i - -i a.ssa \
-map 0:0 -map 0:2 -map 1 \
-crf 18 -preset veryslow -tune zerolatency \
-filter:v yadif \
-c:a copy -c:s copy \
-y a.mkv
重點是 -i a.ssa -map 1 -c:s copyMKV 轉成 mp4
如果要在 ipod 或智慧型手機上看,那就不需要太考慮品質,能用就好。就用上面轉好的 mkv 檔,再轉一次。 如此,既可以用 mkv
保存高品質的影片,再轉成 mp4 的速度也比較快。
這是要注意字幕是圖片格式或是 srt/ass 文字式。
字幕是圖片格式
用 -filter_complex 直接燒錄 :$ ffmpeg -i a.mkv \
-filter_complex '[0:v][0:s:1]overlay[v]' -map [v] -map 0:a \
-vpre ipod -ac 2 -ab 192k \
-y a.mp4
字幕是 srt 或 ass
先處理字幕檔 (前述)
用 -vf subtiles=a.srt 或 -vf ass=a.ass 把字幕燒進 mp4 中。 :
$ ffmpeg -i a.mkv \ -vpre ipod -ac 2 -ab 192k \ -vf subtitles=a.srt \ -y a.mp4
metadata
參考 ffmpeg-metadata[:metadata_specifier] key=value (output,per-metadata) Set a
metadata key/value pair.
An optional metadata_specifier may be given to set metadata on streams
or chapters. See -map_metadata documentation for details.
This option overrides metadata set with -map_metadata. It is also
possible to delete metadata by using an empty value.
For example, for setting the title in the output file :
ffmpeg -i in.avi -metadata title="my title" out.flv
To set the language of the first audio stream :ffmpeg -i INPUT -metadata:s:a:1 language=eng OUTPUT
例子: :-metadata:s:1 title="日語" -metadata:s:2 title="國語" -metadata:s:3 title="中文"
參考資料
FFmpeg wiki:
x264EncodingGuide
直接看 help :
$ ffmpeg --help $ x264 --fullhelp