介绍
ffmpeg命令行的工具格式如下:
ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...
ffmpeg是通用的媒体转换器,可以将广泛的输入(包括实时的抓取和记录设备)-过滤和转换为我们想要的输出格式文件。
ffmpeg可以读取任意数量的输入文件(包括普通文件,管道pipe,网络流,抓取设备等等),使用指定的-i参数,可以写到任意数量的输出文件,输出文件由纯url指定,在命令行上找到的任何不能被解释为选项的内容都被视为输出url。
原则上,每个输入或输出url可以包含任意数量的不同类型的流(视频/音频/字幕/附件/数据)。允许的流的数量和/或类型可能受到容器格式的限制。从哪些流中选择哪些输入将进入哪个输出是自动完成的,或者使用-map选项(请参考ffmpeg文档Stream specifiers 章节)。
要在选项中引用输入文件,必须使用它们的索引(从索引0开始)。例如,第一个输入文件是0,第二个是1,等等。类似地,文件内的流通过它们的索引来引用。例如,2:3是指第三个输入文件中的第四个流。详情可以参考文档Stream specifiers 章节。
作为一般规则,选项将应用于下一个指定的文件。因此,顺序很重要,您可以多次在命令行中使用相同的选项。然后,每次出现都会应用到下一个输入或输出文件。此规则的例外是全局选项(例如日志级别),应首先指定。
视频类指令
读取摄像头
1.查看本机摄像头名称(windows)
ffprobe -list_devices true -f dshow -i dummy
2.播放摄像头数据(windows)
ffplay -f dshow -i video="Integrated Webcam" //其中Integrated Webcam为第一步查询出的摄像头名称
3.将摄像头数据保存为mp4文件(windows)
ffmpeg -f dshow -i video="Integrated Webcam" -vcodec libx264 output.mp4
格式转换
1.从mp4文件中获取h264流
首先说下 MP4的视频H264封装有2种格式:h264和avc1,对于这个细节,很容易被忽略。笔者也是在改编LIVE555流媒体时,增加mp4文件类型支持时遇到了该问题。
(一)首先,从原理上了解一下这2种格式的区别:
AVC1 描述:H.264 bitstream without start codes.一般通过ffmpeg转码生成的视频,是不带起始码0×00000001的。
H264 描述:H.264 bitstream with start codes.一般对于一下HDVD等电影的压制格式,是带有起始码0×00000001的。
ffprobe -i test.mp4
使用上述命令可以查看test.mp4文件的属性:
Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 1000x562 [SAR 1:1 DAR 500:281], 935 kb/s, 24 fps, 24 tbr, 12288 tbn (default)
可以看出我们的测试文件是AVC1格式的,也就是不含有开始码的
ffmpeg -i test.mp4 -an -vcodec copy -bsf:v h264_mp4toannexb test.h264
然后使用命令查看test.h264的属性:
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1000x562 [SAR 1:1 DAR 500:281], 24 fps, 24 tbr, 1200k tbn
可以看出文件是h264格式的,使用16进制查看文件也是具有开始码的,然后就可以使用ffplay或者vlc进行播放.
推流和拉流
1.rtp协议推流
首先, rtp每次推送只能推一路流, 如果用ffmpeg推送普通的影片,比如, mp4, 起码有视频流以及音频流,请在ffmpeg命令里面指定要推送的是视频还是音频, 否则会出现错误。
1.1推送流
推送普通视频 ffmpeg -re -i test.mp4 -metadata title="sdp test" -vcodec copy -an -f rtp rtp://192.168.101.8:11111 -vn -acodec copy -f rtp rtp://192.168.101.8:11113>v.sdp
推送摄像头视频 ffmpeg -f dshow -i video="Integrated Webcam" -b:v 500k -r 30 -g 30 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f rtp rtp://127.0.0.1:30010 > v.sdp
部分参数说明
-re:源文件固有帧率发送数据 -vcodec:设置视频编码/译码器 -acodec:设置音频编码/译码器 copy:copy是ffmpeg的快速编辑的秘诀,表示仅复制,不重新编码和解码,接在-vcodec和-acodec后面。 -f fmt 强迫采用格式fmt -an:disable audio -vn:disable video 最后将播放的信息存放到命令行文件的v.sdp文件下,播放器就可以根据这个sdp进行播放。
1.2接收视频流
ffplay -protocol_whitelist "file,udp,rtp" -i v.sdp
1.3 指定rtp的输出格式
如果不指定输出格式,rtp默认以mpeg4的格式进行输出,有时候我们想指定某个格式(比如为了调试ffmpeg代码或者接收视频流只能接收某个编码的类型),比如我们指定为mjpeg格式输出,因为我自己也在实现一个rtsp协议,需要支持mjpeg格式的支持,那么可以使用以下命令进行指定,如果想指定其他格式,比如h264等,也是类似的,不过需要对rtp协议传输指定的编码比较熟悉。
ffmpeg -i test.h264 -c:v mjpeg -huffman 0 -f rtp rtp://127.0.0.1:30010>v.sdp
上述 -huffman 0 强制mjpeg的rtp传输使用标准的huffman表,需要对mjpeg标准(itu-t81)和mjpeg的rtp传输标准(rfc2435)比较熟悉才能明白为啥要使用标准的huffman表,代码请参考
ffmepg 的 ff_rtp_send_jpeg 接口