主要目的是想用 FFmpeg 接收 UDP 的视频流。

 考虑过用 FFmpeg 的库自己编程,一堆坑:(1)雷霄骅:最简单的推流器 里用到的一些函数和结构体在新版本的 FFmpeg 里被声明为否定了,需要参考 用AVCodecParameters代替AVCodecContext ;(2)FFmpeg 是用 C 写的,在C++里调用需要在开头加上 extern "C",得按 VS2015+ffmpeg 这样写才行。

 最后还是放弃了,直接用 FFmpeg 命令来做。下来从最基础的说起:

一、压缩视频文件

例如将 input.mp4 转码成 output.avi。在Windows下,打开cmd,执行:




ffmpeg -i input.mp4 output.avi

 


 有很多参数可以指定,见ffmpeg官网




 例如:

ffmpeg -i input.mp4 -c:v libx264 -preset ultrafast -b:v 6000k output.avi


 其中,



 :v 代表视频,:a 代表音频;


 -c:v libx264 表示使用264编码器,此时可以设置 -preset,ultrafast 表示最快;


 -b 6000k 指定码率(比特率),码率低时速度快,但失真严重,码率高时反之;


 -vcodec copy 表示不重新编码,在格式未改变的情况采用?;


 -t xxx 表示只编码 xxx 秒,写入 xxx 秒后会停止;

 -frames xxx 表示只编码 xxx 帧,写入 xxx 帧后会停止;


 -f xxx 指定输出格式为 xxx;


 -y 表示如果已存在 output.avi 则将其覆盖;

 -pix_fmt xxx 表示像素格式为 xxx,有时候会提示 pix_fmt 已失效,要改为 pixel_format,视频默认是 yuv420p,还可以是yuv422p、rgb0、rgb24 等。




二、播放视频文件

 使用 ffplay 而不是 ffmpeg,不用写 -i,也不用指定输出,如


ffplay input.mp4

三、.yuv 文件

如果输入文件是原始视频格式 .yuv,则在 -i input.yuv 前面要说明分辨率:

如 -s 1920x1080,有时候会提示 s 已失效,要改为 video_size。

输出文件也可以是 .yuv。

四、发送 UDP 流

参见 雷霄骅

类似压缩视频,只是将输出文件改为 udp 地址,在前面必须指定输出格式,即 -f 。

在 -i 前面要加 -re,表示按帧率发送。

ffmpeg -re -i input.mp4 -f h264 udp://233.233.233.233:6666


如果输入文件是 .yuv 则前面还要说明分辨率,即 -s。

-f rawvideo 表示发送的格式为原始未打包视频流? 由于未打包,无法接收回来。

要想发送未压缩的视频流可以打包成 TS 流,即 -f mpegts。

ffmpeg -re -s 1920x1080 -i input.yuv -b:v 60000k -f mpegts udp://233.233.233.233:6666

五、接收/播放 UDP 流

类似压缩视频,只是将输入文件改为 udp 地址,在前面要说明格式

ffmpeg -f h264 -i udp://233.233.233.233:6666 output.avi



如果是 rawvideo 格式,前面还要写 -s,但反正 rawvideo 没用。

如果接收的是 TS 流,似乎不需要在前面说明格式,加了 -f mpegts 反而报错。


ffmpeg -i udp://233.233.233.233:6666

 播放 udp 流和播放视频文件类似


ffplay udp://233.233.233.233:6666