打印
[项目合作]

FFmpeg实现视频流多平台分发技术方案

[复制链接]
985|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
价格:1 元
本帖最后由 酷洵软件 于 2019-6-11 16:00 编辑

一、 概述

应用QT 和C++技术,采集视频设备的数据流,通过分发技术方案,可以使多个终端设备接收该视频流;视频器材可以是任何基于IP网络的视频设备,如视频眼镜、摄像机等。接收分发视频流的终端基本支持所有设备,如PC机、IOS手机、Android手机等;该技术方案主要用来解决两个问题:视频安全可控【防止视频数据泄露】;大幅度节约视频应用成本【目前使用视频云服务的成本相当高昂】。

二、 技术方案总览图框架图

总体分三层结构,视频采集层、数据源管理层和终端接收层,如下图所示:




三、 视频源采集技术

可以通过如下步骤采集视频流(本例以广播包形式说明),视频采集设备可以是PC或者手机终端【本例以Android手机端作为视频采集端,如何编译FFMPEG Android,请参考:https://www.apps121.com/2019/03/11/ffmpeg4-1-androidlibwindows_compile_successfully/】

1、 启动采集设备上的视频采集程序,搜素网络中的视频设备:

2、 捕获搜索到视频设备中的视频流;

代码说明如下:

A、 创建QudpSocket 对象,使用bind绑定端口

B、 定时发送网络广播包

C、解析出RTSP 视频流的地址

D、拉取设备视频流数据

a) 循环使用函数 av_read_frame 读取视频流中的数据到AVPacket ,AVPacket结构特别重要【可以作为未解码的原始数据包直接转发到服务端;根据需求再次编码;直接在设备采集端解码并播放视频;可以进行视频的数据的录制等】;

b) 需要设置关键帧信息 : AVCodecContext中的两个参数分别为time_base.num 和time_base.den

3、 分发的数据流采集

设备采集端需要制作两路视频,一路视频用于采集端播放;另一路用于传到服务端,用于分发使用;

采集端播放代码比较简单:

首先avcodec_decode_video2解码视频流数据,使用sws_scale适配出合适的帧数据,最后创建Qimage对象显示就可以的

注释:Android 显示帧数据使用Image对象就可以的,通过QquickImageProvider格式化显示的帧数据

用于服务端分发流主要有三种方式:

a) 直接使用解码之后的帧数据

首先把帧数据写入QbyteArray对象,再压缩,最后通过网络传输到服务端

QImage image;

this->OpQueue(image,1);

QByteArray byte;

QBuffer buffer(&byte);

buffer.open(QIODevice::WriteOnly);

image.save(&buffer, "JPG", g_nFrameLevelTmp);

byte = qCompress(byte);

b) 使用未解码的原始数据

把通过函数av_read_frame读取原始数据流AVPacket做个数据拷贝,再把数据写入QbyteArray中同时进行压缩,最后通过网络传输到服务器。

c) 重新编码视频流数据【Android系统FFMPEG编译的时候需要添加H264支持的,默认只支持解码的,不支持编码的,需要特别主要】

创建H264编码器,主要是如下三个函数 avcodec_find_decoder(AV_CODEC_ID_H264)

avcodec_alloc_context3

avcodec_open2

解码器主要参数设置如下:

m_pVideoEnCtx->codec_id = AV_CODEC_ID_H264;

m_pVideoEnCtx->codec_type = AVMEDIA_TYPE_VIDEO;

m_pVideoEnCtx->pix_fmt = AV_PIX_FMT_YUV420P;

m_pVideoEnCtx->width = 1280;

m_pVideoEnCtx->height = 720;

m_pVideoEnCtx->bit_rate = 400000;

m_pVideoEnCtx->gop_size = 75 ;

m_pVideoEnCtx->time_base.num = 1;

m_pVideoEnCtx->time_base.den = 25;

m_pVideoEnCtx->max_b_frames = 0;

m_pVideoEnCtx->has_b_frames = 0;

m_pVideoEnCtx->i_quant_factor = 2;

av_opt_set(m_pVideoEnCtx->priv_data, "preset", "slow", 0);

av_opt_set(m_pVideoEnCtx->priv_data, "tune", "zerolatency", 0);

重新编码视频流数据,这一步可以设置码率、大小等定制化参数;编码之序列化数据到QbyteArray中并且压缩,最后通过网络传输到服务端

d) 三种方式的比较

直接传输视频帧数据,逻辑简单,针对小分辨率和局域网网比较实用;

传输未解码的视频包,逻辑相当复杂点,但是数据压缩率极高,能很好的满足公网传输

重新编码方式,主要应用于多功能定制用途,灵活性特别好,满足不同的视频质量和网络带宽要求

四、 服务端分发技术

服务端主要用户账号管理,提供访问视频数据权限;视频源数据管理,数据存档、过滤以及 以及视频数据下发给各个终端设备。

服务端流程示意图:


五、 接收视频流的终端设备

视频终端设备,连接服务端并接收视频数据,视频终端设备有可能需要处理视频数据,如未解码的原始视频数据,需要终端解码并显示;针对Android视频库的的编译方式,请参照:https://www.apps121.com/2019/03/11/ffmpeg4-1-androidlibwindows_compile_successfully/

六、 结束语

Qt&C++ 基于FFMPEG库的视频流分发技术方案可以有效的节约成本,保证对视频数据的绝对控制和处理;

详细的代码细节,如有兴趣,可以私聊沟通,谢谢!

原文参考了:https://www.apps121.com/2019/06/11/qtcffmpeg_slu/

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

8

帖子

1

粉丝