在前面一个博客(地址在这里 )中,我们做到了将采集的摄像头数据编码为H.264,接下来我么讨论下如何将H.264发送,在接收端接收解码并播放。和上一篇编码的博客一样,我们也是直接调用ffmpeg.exe和ffplay.exe文件,内部的具体操作需要抽时间去阅读。
1.传输
UDP是一种无连接的传输层协议,不对传送数据包进行可靠性保证,适合一次性传输少量数据。
我们在编码指令的基础上增加指令,将编码后的H.264封装为UDP并发送至组播地址。
ffmpeg -f vfwcap -i 0 -vcodec libx264 encoded.h264 -f h264 udp://127.0.0.1:6666
我这里是用自己的电脑往自己的电脑上发送,测试用,所以地址必须是:127.0.0.1。后面的6666是端口号,自己设置,只要和接收端保持一致即可。 考虑到提高编码速度,可以添加-preset:v ultrafas和-tune:v zerolatency两个选项。如下所示:
ffmpeg - f vfwcap - i 0 - vcodec libx264 encoded.h264 -preset:v ultrafast -tune:v zerolatency -f h264 udp ://127.0.0.1:6666
高分辨率的情况下,UDP传输会有丢包的现象。为了避免这种情况,可以添加参数-s(eg:-s 320x240)调整分辨率。 同理,可以将H.264封装为RTP并发送至组播地址:
ffmpeg -f vfwcap -i 0 -vcodec libx264 encoded.h264 -preset:v ultrafast -tune:v zerolatency -f rtp rtp://127.0.0.1:6666 >test.sdp
也可以把H.264发送至RTMP服务器: ffmpeg - f vfwcap - i 0 - vcodec libx264 encoded.h264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp ://localhost/oflaDemo/livestream
至此,发端的全部代码如下:
#include <stdio.h>
#include <windows.h>
int main( )
{
char* encoded = "ffmpeg -f vfwcap -i 0 -vcodec libx264 encoded.h264 -f h264 udp://127.0.0.1:6666 ";
WinExec(encoded, SW_SHOW);
return 0;
}
接收端要实现的功能是解码和播放。在这里,我们只需要用ffplay打开传输过来的H.264文件,在打开的过程中,ffplay.exe文件会自动将H.264解码进行播放。只要udp的端口保持一致即可。
命令如下:
ffplay -f h264 -analyzeduration 100000 -max_delay 100000 -fflags nobuffer udp://127.0.0.1:6666
在VS工程里的全部代码:
#include <stdio.h>
#include <windows.h>
int main()
{
char* play = "ffplay -f h264 -analyzeduration 100000 -max_delay 100000 -fflags nobuffer udp://127.0.0.1:6666";
WinExec(play, SW_SHOW);
return 0;
}
3.测试
首先运行发端的代码:
运行发端代码后,在另一个工程里运行收端代码:
在发端的工程目录下,我们找到保存在本地H.264文件,用VLC media player播放,可以与收端播放的视频做比较。
到这里,用ffmpeg调用摄像头,编码、发送、解码、播放的全部过程就结束了,其内部的具体代码流程以后要慢慢的弄清楚。