容器格式 V.S. 编解码格式
容器格式(container: avi,mp4,wmv,mpeg\mpg)
编解码格式(codec: mpeg4、h263、h264)
参考:
https://www.jianshu.com/p/f2f82a97adb2
https://blog.csdn.net/qiurisuixiang/article/details/54943657
更深入的了解可以参见博客:https://blog.csdn.net/class_brick/article/details/82893967
“A complete, cross-platform solution to record, convert and stream audio and video.” 可以实现视频和音频的转码、裁剪、合并等。
安装:
sudo apt-get install ffmpeg
如下依赖项自动安装:
The following additional packages will be installed:
libavdevice-ffmpeg56 libavfilter-ffmpeg5 libbs2b0 libflite1 libopenal-data
libopenal1 libsodium18 libvdpau1 libzmq5 mesa-vdpau-drivers vdpau-driver-all
Suggested packages:
ffmpeg-doc libvdpau-va-gl1 nvidia-vdpau-driver
nvidia-legacy-340xx-vdpau-driver
The following NEW packages will be installed:
ffmpeg libavdevice-ffmpeg56 libavfilter-ffmpeg5 libbs2b0 libflite1
libopenal-data libopenal1 libsodium18 libvdpau1 libzmq5 mesa-vdpau-drivers
vdpau-driver-all
0 upgraded, 12 newly installed, 0 to remove and 30 not upgraded.
Need to get 17.3 MB of archives.
ffprobe -show_streams -i video.h264
ffprobe -v error -show_format -show_streams video.h264
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 video.h264
或者
ffmpeg -i video.h264 -map 0:v:0 -c copy -f null -
-c/-codec copy,保留原始视频编码格式,不重新做视频编解码,因此非常快;
-map [-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]],因此,-map 0:v:0表示第一个输入文件的第一个video stream;
-f fmt (input/output). Force input or output file format.
参考:https://stackoverflow.com/questions/2017843/fetch-frame-count-with-ffmpeg
4.1 只转换容器容器格式,不改变编解码格式
Streamcopy: input file _demuxer_> encoded data packets_muxer__ > outputfile
ffmpeg -i input.avi -codec copy out.mp4
-c/-codec copy,保留原始视频编码格式,不重新做视频编解码,因此非常快;
注意:如果未加-codec copy,即ffmpeg -i input.avi out.mp4,则使用默认视频编解码器进行encoder和decoder,因此速度比较慢,属于同时转换编解码格式&容器格式的转换。
4.2 同时转换编解码格式&容器格式的转换
Transcoding process:input file _demuxer_> encoded data packets _decoder__>decoded frames _encoder_> encoded data packets __muxer__ > outputfile :
ffmpeg -i input.avi -vcodec h264 out.mp4
-i 表示输入视频选项;
-vcodec指定了视频编码格式为h264。
改变帧率(播放速度):
ffmpeg -r f_output -i input output
-r f_output 表示帧率,例如 -r 20将output视频的帧率设为20fps。ouput和input视频的帧总数不变,视频时长根据修改的帧率做调整,即t_output=t_input*f_input/f_output.
改变码流:
ffmpeg -i input -r f_output output
output视频总时长与input视频相同,output视频的码流设置成-r f_output。
按时间剪切:
ffmpeg -i video.h264 -ss 00:00:50.0 -c copy -t 00:00:20.0 video_copy.h264
从50s开始,向后剪切20s。
-c[:stream_specifier] codec. Select an encoder (when used before an output file) or a decoder (when used before an input file) for one or more streams. -c:v 选中video stream, -c:a选中audio stream。-c 表示选中所有stream。
注意:如果容器中不包含时间信息,则无法通过此工具裁剪,因为ffmpeg不支持根据帧数剪切,只支持基于时间剪切。
参考:https://blog.csdn.net/angus_17/article/details/80696989
按帧剪切:
Filtering: input file _demuxer_> encoded data packets _decoder_>decoded frames__simple filtergraph >filtered frames _encoder_> encoded data packets __muxer__ > outputfile
ffmpeg -i input.h264 -vf "select=between(n\,20\,200)*not(mod(n\,2))" -vsync 0 ./cut_result.h264
其中,Simple filtergraphs are configured with the per-stream -filter option (with -vf and -af aliases for video and audio respectively). 使用filter进入视频先解码,再编码的模式,则不能再使用stream copy。
-vf: filtergraph. Create the filtergraph specified by filtergraph and use it to filter the stream. This is an alias for "-filter:v".
select filter中between(n\,20\,200)*not(mod(n\,1))中 between内的参数为开始帧和结束帧,not(mod n\,2)中的参数为间隔数
关于filters的详细文档可以参见:http://ffmpeg.org/ffmpeg-filters.html
PS:
-vsync 控制时间戳
Video sync method. For compatibility reasons old values can be specified as numbers. Newly added values will have to be specified as strings always.0, passthrough. Each frame is passed with its timestamp from the demuxer to the muxer.
1, cfr. Frames will be duplicated and dropped to achieve exactly the requested constant frame rate.
2, vfr. Frames are passed through with their timestamp or dropped so as to prevent 2 frames from having the same timestamp.
drop. As passthrough but destroys all timestamps, making the muxer generate fresh timestamps based on frame-rate.
-1, auto. Chooses between 1 and 2 depending on muxer capabilities. This is the default method.
建立filelist.txt文件,里面写入需要合并(时间上)的视频信息:
file '1.h264'
file '2.h264'
file '3.h264'
file '4.h264'
运行命令:
ffmpeg -f concat -i filelist.txt -c copy output.h264
将多个视频在空间上拼合成多个窗口,播放时同时显示。
垂直拼接:
ffmpeg -i input0.avi -i input1.avi -filter_complex "[0:v]scale=1600:-1[v0];[v0][1:v]vstack=inputs=2" output.avi
选中[0:v]第一个视频的video stream,
scale=1600:-1, scale为缩放滤镜,宽度为1600,-1表示输出时保持原始的宽高比。
水平拼接:
ffmpeg -i input0.avi -i input1.avi -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' -map [vid] -c:v libx264 -crf 23 -preset veryfast output.avi
PS:
-filter[:stream_specifier] filtergraph (output,per-stream). 单进->单出。例如:单一视频文件的格式转换。Create the filtergraph specified by filtergraph and use it to filter the stream. filtergraph is a description of the filtergraph to apply to the stream, and must have a single input and a single output of the same type of the stream.
-filter_complex: filtergraph (global). 多进->单出 or 单进->多出 or 多进->多出。例如,多个视频拼合一个文件。Define a complex filtergraph, i.e. one with arbitrary number of inputs and/or outputs.
关于filter的详细文档可以参见:http://ffmpeg.org/ffmpeg-filters.html
参考:https://stackoverflow.com/questions/11552565/vertically-or-horizontally-stack-several-videos-using-ffmpeg