FFmpeg处理流程与命令

目前的情况是输入端采用DirectShow技术捕获音视频,然后对视频进行h.264编码,对音频进行aac编码,输出端则是生成文件,接下来还要进一步扩展输入端和输出端,以支持文件、桌面输入,RTSP、RTMP、HTTP等流式协议输出。
AVStream 即是流通道。例如我们将 H264 和 AAC 码流存储为MP4文件的时候,就需要在 MP4文件中增加两个流通道,一个存储Video:H264,一个存储Audio:AAC。(假设H264和AAC只包含单个流通道)。
1、FFmpeg处理音视频流程(记住)
输入文件 --demuxer(解复用)–> 编码数据包 --decoder–> 解码后的数据帧 --encoder–> 编码数据包 --muxer(复用)–> 输出文件
FFmpeg处理流程与命令_第1张图片
大流程可以划分为输入、输出、转码、播放四大块。其中转码涉及比较多的处理环节,从图中可以看出,转码功能在整个功能图中占比很大。转码的核心功能在解码和编码两个部分,但在一个可用的示例程序中,编码解码与输入输出是难以分割的。解复用器为解码器提供输入,解码器会输出原始帧,对原始帧可进行各种复杂的滤镜处理,滤镜处理后的帧经编码器生成编码帧,多路流的编码帧经复用器输出到输出文件。

FFMPEG中结构体很多。最关键的结构体可以分成以下几类:
a) 解协议(http,rtsp,rtmp,mms)
AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)
b) 解封装(flv,avi,rmvb,mp4)
AVFormatContext主要存储视音频封装格式中包含的信息;AVInputFormat存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat 结构。
c) 解码(h264,mpeg2,aac,mp3)
每个AVStream存储一个视频/音频流的相关数据;每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。
d) 存数据
视频的话,每个结构一般是存一帧;音频可能有好几帧

解码前数据:AVPacket
解码后数据:AVFrame
他们之间的对应关系如下所示:雷神写的
FFmpeg处理流程与命令_第2张图片
av_register_all 注册库所支持的容器格式及其对应的CODEC。
avformat_open_input 打开多媒体文件流,并读取文件的头,将读取到的信息填充到AVFormatContext结构体中。在使用结束后,要调用avformat_close_input关闭打开的流
avformat_find_stream_info 上面提到,avformat_open_input只是读取文件的头来得到多媒体文件的信息,但是有些文件没有文件头或者文件头的格式不正确,这就造成只调用
avformat_open_input可能得不到解码所需要的必要信息,需要调用 avformat_find_stream_info进一步得到流的信息。
通过上面的三个函数已经获取了对多媒体文件进行解码的所需要信息,下面要做的就是根据这些信息得到相应的解码器。
结构体AVCodecContext描述了编解码器的上下文信息,包含了流中所使用的关于编解码器的所有信息,可以通过 AVFormatContext->AVStream->AVCodecContext来得到,在有了AVCodecContext后,可以通过codec_id来找到相应的解码器,具体代码如下:

AVCodec* pCodec = nullptr;
pCodecCtxOrg = pFormatCtx->streams[videoStream]->codec; // codec context
// 找到video stream的 decoder
pCodec = avcodec_find_decoder(pCodecCtxOrg->codec_id);

avcodec_find_decoder 可以通过codec_id或者名称来找到相应的解码器,返回值是一个AVCodec的指针。
avcodec_open2 打开相应的编解码器。
av_read_frame 从流中读取数据帧暂存到AVPacket中。
avcodec_decode_video2 从AVPacket中解码数据到AVFrame中。

FFmpeg处理流程与命令_第3张图片
3、基本信息查询命令15个
-version 显示版本。
-formats 显示可用的格式(包括设备)。
-demuxers 显示可用的demuxers。
-muxers 显示可用的muxers。
-devices 显示可用的设备。
-codecs 显示libavcodec已知的所有编解码器。
-decoders 显示可用的解码器。
-encoders 显示所有可用的编码器。
-bsfs 显示可用的比特流filter。
-protocols 显示可用的协议。
-filters 显示可用的libavfilter过滤器。
-pix_fmts 显示可用的像素格式。
-sample_fmts 显示可用的采样格式。
-layouts 显示channel名称和标准channel布局。
-colors 显示识别的颜色名称。
4.录制命令

  • ffmpeg录制视频

    1. ffmpeg -f avfoundation -i 1 -r 30 out.yuv
        -f 指定使用avfoundation库采集数据
        -i 指定从哪采集数据,1代表视频数据来自屏幕,0代表视频数据来自摄像头
        -r 指定帧率
        out.yuv 采集后的视频数据保存成为yuv数据,yuv是一种原始视频数据,没有任何的压缩 
        ctrl + c 结束,在命令行下起着终止当前执行程序的作用
    2. ffplay -s 2880x1800 -pix_fmt uyvy422 out.yuv
        -s 指定录制时分辨率/尺寸大小
        -pix_fmt 指定录制时像素格式,以正确渲染
        使用ffplay播放刚录的视频
    3. ffmpeg -f avfoundation -list_devices true -i ""
    查询avfoundation库所支持的设备列表,音频代表的数字放在:后面
    
  • ffmpeg录制声音

    1. ffmpeg -f avfoundation -i :0 out.wav
        -f 指定使用avfoundation库采集数据
        -i 指定从哪采集数据 :0代表音屏设备,数字放在:后面代表音屏数据(不一定正确,关键 通过ffmpeg -f avfoundation -list_devices true -i "" 查看各个数值代表的含义)
        out.yuv 采集后的音屏数据保存成为wav数据
    

5、分解/复用命令:文件格式的转换
流程 输入文件 --demuxer(解复用)–> 编码数据包 --muxer(复用)–> 输出文件
多媒体格式的转换

  1. ffmpeg -i out.mp4 -vcodec copy -acodec copy out.flv
    -i 输入文件
    -vcodec 视频编解码处理方式是copy
    -acodec 音频编解码同上
    out.flv 输出为flv,其中out是视频名称可改
  2. 抽取视频,不包含声音
    ffmpeg -i out.mp4 -vcodec copy -an out.h264 // -an a代表audio n代表no 输出结果不包括视频
    ffplay out.h264
  3. 抽取音频,不包含视频
    ffmpeg -i out.mp4 -vn -acodec copy out.aac
    ffplay out.aac
    6、处理原始数据命令
    原始数据是指ffmpeg解码后的数据,对于视频就是yuv数据,对于音频就是pcm数据.
    通过ffmpeg提取yuv数据
  4. ffmpeg -i out.mp4 -an -c:v rawvideo -pixel_fmts yuv420p out.yuv
    -i 输入文件
    -an a代表audio n代表no 输出结果不包括视频
    -c:v 对视频进行编码,使用rawvideo原始视频进行编码
    -pix_fmt 指定像素格式yuv420p
  5. ffplay -s 1336x752 out.yuv
    原始数据没有宽和高,播放器无法正确解析,需要指定原始视频的分辨率 -s 1336x752 分辨率在ffmpeg提取yuv视频时已显示出来过
    通过ffmpeg提取pcm数据
  6. ffmpeg -i out.mp4 -vn -ar 44110 -ac 2 -f s16le out.pcm
    -vn 不需要视频
    -ar a代表audio r代表read,音频的采样率是44.1k
    -ac a代表audio c代表channel,2代表声音是双声道
    -f 音频pcm数据其数据存储格式是s16le
    out.pcm 输出的文件名
  7. ffplay -ar 44110 -ac 2 -f s16le out.pcm
    需要告知ffplay播放
    7、各种滤镜命令
    视频加水印,去水印,画中画,视频的裁剪,音频倍速等可使用滤镜实现
    ffmpeg滤镜处理流程
    解码后的数据帧-filter->过滤后的数据帧-encoder-> 编码数据包
    FFmpeg处理音视频流程(和滤镜流程对照理解 )
    输入文件 --demuxer(解复用)–> 编码数据包 --decoder–> 解码后的数据帧 --encoder–> 编码数据包 --muxer(复用)–> 输出文件
    滤镜命令:视屏裁剪命令(视频画面大小裁剪不是播放过程中裁剪)
  8. ffmpeg -i out.mp4 -vf crop=in_w-200:in_h-200 -c:v libx264 -c:a copy out2.mp
    -i 指定多媒体文件
    -vf 视屏滤镜,crop代表一种滤镜名字,后面跟上参数,in_w-200表示本身视频宽度减去200,in_h-200表示本身视频高度减去200
    -c:v libx264 告诉ffmpeg此视频的编码器是libx264
    -c:a copy 不对音频做特殊处理
    out.mp4 输出文件
    8、裁剪与合并命令
    ffmpeg音视频裁剪
  9. ffmpeg -i in.mp4 -ss 00:00:00 -t 10
    -ss 视频裁剪的起始时间
    -t 10 裁剪多长时间,单位s,10s
    out.ts 输出文件
    9、图片视频互转命令
    10、直播相关命令

    1)直播推流
    ffmpeg -re -i out.mp4 -c copy -f flv rtmp://server/live/streamname
    -re 减慢帧率速度,让帧率与视频真正帧率保持同步
    -i out.mp4 需要推出去的文件
    -c 音视频编解码,copy音频与视频的参数不变;如果专门指定音频那就是-acodec,如果专门指定视频那就是-vcodec
    -f flv 推出去的文件格式是flv
    rtmp://server/live/streamname 服务器地址,将视频推送到rtmp服务器上,其他端就可以从rtmp服务器上拉流看到直播影像
    2)直播拉流
    ffmpeg -i rtmp://server/live/streamname -c copy dump.flv
    实例 ffmpeg -i http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8 -c copy dump.m3u8 (拉取什么格式就保存成什么格式)
    ffplay dump.m3u8
    -c copy 对于拉到的数据流不做重新编码,不对音视频参数做任何处理
    dump.flv 拉取到本地后保存成 dump.flv 文件

你可能感兴趣的:(流媒体)