ffmpeg簡單實戰

什麼是ffmpeg

ffmpeg is a very fast video and audio converter that can also grab from a live audio/video source. It can also
convert between arbitrary sample rates and resize video on the fly with a high quality polyphase filter.html

簡單的說,ffmpeg乃江湖神器。它能幫你將視頻一幀幀錄成圖片,能幫你自由轉換視頻的格式,什麼加字幕加音軌啦,什麼錄製屏幕啦,都很easylinux

原理

ffmpeg命令都是長的嚇人,可是基本原理仍是簡單的git

一張圖~web

s

基本上就是這樣的流程:輸入文件==>被分離器分離的數據包==>被解碼的數據幀==>被編碼的數據包==>輸出文件ubuntu

實戰

首先,咱們能夠給視頻加上字幕~vim

好比說我有一步電影信息以下bash

cecil@cecil-Aspire-4750  /media/cecil/FreeAgent GoFlex Drive/豆瓣250  ffprobe \[這個男人來自地球\].Man.From.Earth.DVDRip.Xvid.TFE.cht\&eng.mkv
avprobe version 0.8.10-6:0.8.10-0ubuntu0.12.10.1, Copyright (c) 2007-2013 the Libav developers
  built on Feb  6 2014 20:57:40 with gcc 4.7.2
[matroska,webm @ 0x9895100] Estimating duration from bitrate, this may be inaccurate
Input #0, matroska,webm, from '[這個男人來自地球].Man.From.Earth.DVDRip.Xvid.TFE.cht&eng.mkv':
  Duration: 01:27:08.12, start: 0.000000, bitrate: 640 kb/s
    Stream #0.0(eng): Video: h264 (High), yuv420p, 1280x720, PAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc
    Stream #0.1: Audio: ac3, 48000 Hz, 5.1, s16, 640 kb/s (default)

能夠清晰的看到,這個電影只有兩個流:一個是視頻流,一個是音頻流,尚未字幕呢。架構

而後我加一個字幕app

✘ cecil@cecil-Aspire-4750  /media/cecil/FreeAgent GoFlex Drive/豆瓣250  /media/cecil/51650c88-09b9-4cda-a034-8f7012af8b19/ceclinux/bin/ffmpeg -i \[這個男人來自地球\].Man.From.Earth.DVDRip.Xvid.TFE.cht\&eng.mkv -i \[這個男人來自地球\].Man.From.Earth.DVDRip.Xvid.TFE.chs\&eng.srt -c copy -map 0:0 -map 1:0   這個男人來自地球.mkv
ffmpeg version 2.2.git Copyright (c) 2000-2014 the FFmpeg developers
  built on Apr 24 2014 21:31:10 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
  configuration: --prefix=/home/ceclinux/ffmpeg_build --extra-cflags=-I/home/ceclinux/ffmpeg_build/include --extra-ldflags=-L/home/ceclinux/ffmpeg_build/lib --bindir=/home/ceclinux/bin --extra-libs=-ldl --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab
  libavutil      52. 78.100 / 52. 78.100
  libavcodec     55. 58.105 / 55. 58.105
  libavformat    55. 37.101 / 55. 37.101
  libavdevice    55. 13.100 / 55. 13.100
  libavfilter     4.  4.100 /  4.  4.100
  libswscale      2.  6.100 /  2.  6.100
  libswresample   0. 18.100 /  0. 18.100
  libpostproc    52.  3.100 / 52.  3.100
Input #0, matroska,webm, from '[這個男人來自地球].Man.From.Earth.DVDRip.Xvid.TFE.cht&eng.mkv':
  Metadata:
    encoder         : libebml v0.7.9 + libmatroska v0.8.1
    creation_time   : 2010-02-03 01:40:21
  Duration: 01:27:08.13, start: 0.000000, bitrate: 7168 kb/s
    Stream #0:0(eng): Video: h264 (High), yuv420p, 1280x720, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc
    Stream #0:1: Audio: ac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
Input #1, srt, from '[這個男人來自地球].Man.From.Earth.DVDRip.Xvid.TFE.chs&eng.srt':
  Duration: N/A, bitrate: N/A
    Stream #1:0: Subtitle: subrip
File '這個男人來自地球.mkv' already exists. Overwrite ? [y/N] y
Output #0, matroska, to '這個男人來自地球.mkv':
  Metadata:
    encoder         : Lavf55.37.101
    Stream #0:0(eng): Video: h264 (H264 / 0x34363248), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 23.98 fps, 1k tbn, 1k tbc
    Stream #0:1: Subtitle: subrip
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #1:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame=31461 fps=1033 q=-1.0 size=  969127kB time=00:21:54.70 bitrate=6038.7kbits/s

這裏 -i 表示輸入的文件,map表示流的映射,-map 0:0 -map 1:0表示將第一個文件的第一個流(視頻流)和第二個文件的第一個流(字幕流)進行映射
-c 表示拷貝流ide

混入後。。

cecil@cecil-Aspire-4750  /media/cecil/FreeAgent GoFlex Drive/豆瓣250  ffprobe 這個男人來自地球.mkv
avprobe version 0.8.10-6:0.8.10-0ubuntu0.12.10.1, Copyright (c) 2007-2013 the Libav developers
  built on Feb  6 2014 20:57:40 with gcc 4.7.2
[matroska,webm @ 0x8839100] Estimating duration from bitrate, this may be inaccurate
Input #0, matroska,webm, from '這個男人來自地球.mkv':
  Metadata:
    ENCODER         : Lavf55.37.101
  Duration: 01:27:08.18, start: 0.000000, bitrate: N/A
    Stream #0.0(eng): Video: h264 (High), yuv420p, 1280x720, PAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
    Stream #0.1: Subtitle: [0][0][0][0] / 0x0000 (default)
Unsupported codec with id 94210 for input stream 1

很明顯的是,新的合成視頻是沒有聲音的。若是想要有聲音怎麼辦?你懂的
另外,若是你想要用這種方式加入字幕的話,字幕的格式須要注意,最好的utf-8的,否則加入的字幕在某些播放器上會出現點問題,好比個人gb18030格式的字幕加入到視頻後,smplayer是亂碼,vlc沒問題。。。

有一個轉換字符集的命令

cecil@cecil-Aspire-4750  ~  iconv -f gb18030 -t UTF-8 \[這個男人來自地球\].Man.From.Earth.DVDRip.Xvid.TFE.chs\&eng.srt > \[這個男人來自地球\].Man.From.Earth.DVDRip.Xvid.TFE.chs\&eng-utf8.srt

嗯,暫時找不到方便的方法,必需要提供原字符集。若是有更好的請告訴我,謝謝

第二種加入字幕方法

第一種咱們使用流的拷貝,第二種。。。直接嵌入視頻!

首先,你先要看看本身的ffmpeg有沒有帶subtitle這個filter

cecil@cecil-Aspire-4750  ~  ffmpeg -filters|grep sub

沒有就是一個比較悲劇的事情,須要點這裏編譯了

ffmpeg compilation

編譯完成以後運行

✘ cecil@cecil-Aspire-4750  /media/cecil/FreeAgent GoFlex Drive/豆瓣250  /media/cecil/51650c88-09b9-4cda-a034-8f7012af8b19/ceclinux/bin/ffmpeg -i \[這個男人來自地球\].Man.From.Earth.DVDRip.Xvid.TFE.cht\&eng.mkv -vf subtitles='\[這個男人來自地球\].Man.From.Earth.DVDRip.Xvid.TFE.chs\&eng-utf8.srt'  ~/這個aa.mkv

若是你去實踐過,會發現一個問題:第二種方法實在是太耗時間太耗cpu了,爲何呢?

簡單的說,第二種方法將字幕「渲染」進了視頻,也就是說,對於每一幀圖像,都加上了字幕,把原來該存在的像素點都覆蓋成了字幕文字,電腦須要一幀一幀的處理數據。

那麼filter是什麼東西

d

也就是說,原始的ffmpeg架構,作了一點點手腳,對每一幀處理了下。subtitle filter就是一個在視頻上畫字幕的filter

不信的話你能夠用ffprobe探測下新生成的文件,已經沒有字幕流了。

可是第一方法那個copy則不一樣

Stream copy is a mode selected by supplying the copy parameter to the ‘-codec’ option. It makes ffmpeg omit the decoding and encoding step for the specified stream, so it does only demuxing and muxing. It is useful for changing the container format or modifying container-level metadata. The diagram above will, in this case, simplify to this:

copy
ffmpeg根本不須要作什麼加碼啊,解碼啊。。直接分流和混流就好了,固然快了~

而後是作動圖

利用ffmpeg + convert 兩大殺器,咱們能夠弄一個從電影裏抓一段的轉化爲gif動圖腳本

#!/bin/bash

#一個將mkv視屏中的一段作成動態gif的腳本
#命令 ./video2gif.sh 視屏路徑 橫屏分辨率 開始時間 時長

mkdir png
#scale - If the value for width or height is -1, the scale filter will use, for the respective output size, a value that maintains the aspect ratio of the input image.
# r - set the frame rate
## -vf scale 送到scale過濾器
if [[ $2 == "0" ]];then
    ffmpeg -ss $3 -i $1 -t $4 -r 20 png/snapshot%05d.png
else
    ffmpeg -ss $3 -i $1 -t $4  -vf scale=${2}:-1 -r 20 png/snapshot%05d.png
fi
#delay - display the next image after pausing
# pattern removal - http://bash.sourceforge.net/Guide/bashguide05.html
# 移除後綴
convert -layers Optimize -delay 4/100 png/snapshot*.png ${1%%.*}.gif
rm -rf png

這裏我用scale這個filter來調整截成的圖片的大小。

隨便作幾張影史經典的動圖

搏擊俱樂部 -- 帶着妹子一塊兒看炸大樓

bj

肖申克的救贖 -- 逃出監獄,感覺自由

xsk

有但願的男人 -- 呵呵

yxw

沒了。

相關文章
相關標籤/搜索