RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265

     众所周知的原因原生的RTMP只支持H264 并不支持H265的传输,之前的项目基于海思3531DV200平台的多路输入 多路输出 基于FFMpeg 拉RTSP的流 然后通过海思硬件解码然后在编码成较小的分辨率 通过RTMP推流到服务器端 项目已经基本结束。

    然后领导 要求要实现RTMP H265的实现。从上周五2021.12.03 接到这个任务,到今天12.10正好一星期 已经基本上实现。中间穿插了一些其他的杂事。下面来说说这个过程吧 。

之前测试的都是3531拉流推流 到Nginx 或者SRS服务器 然后用VLC测试播放 H264的时候,一点问题都没有。

提示:不想折腾的可以直接点击下面 已经改好的 源代码  直接下下来编译就可以 

播放端ffplay 需要SDL的支持  需要安装SDL ubunt可以直接apt安装  windows下需要 编译安装

支持H265的RTMP源码 (推流端 服务器端 播放端)

下载完之后有三个文件夹 对应推流端 服务器端 播放端
1.ffmpeg 直接执行./build.sh脚本 之后 install make install(需要提前安装SDL)
2.SRS 直接执行trunk目录下的build.sh脚本  make 之后 需要的操作如下:
    
    让配置生效
    ./objs/srs -c conf/srs.conf

    srs 运行
    ./etc/init.d/srs start

    在运行过程中查看log
    tail -f ./objs/srs.log

    停止srs服务器
    ./etc/init.d/srs stop

    重新打开srs服务器
    ./etc/init.d/srs restart
3.推流端需要打开宏 QMCY_ADD_H265_SUPPORT
    然后直接调用srs_h265_write_raw_frames 函数就可以


如有问题  可以留言讨论

先看效果图 ubunt 直接用ffplay播放 h265的rtmp流 

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第1张图片

换成H265之后都有问题了 

1.首先是推流端 用的是srs_librtmp.cpp那个开源库

H264发送的时候很简单 调用如下代码即可

nRet = srs_h264_write_raw_frames(rtmp_handle, packet.data, packet.size, video_dts, video_dts);

H265就要自己扩展了 网上搜了下 参考

实现如下接口 

nRet = srs_h265_write_raw_frames(rtmp_handle, packet.data, packet.size, video_dts, video_dts);

基本上是参照 别人的代码来修改的 别人的是 很多个源文件的代码 ,我这只有一个源文件,所以需要自己慢慢搜索 慢慢添加进来 。做完这一步之后 并不知道 有没有问题 。需要最终能播放出来没问题 才能验证。修改地方挺多的 但是感觉很多地方没有用到 因为 我们只需要推流

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第2张图片

2.服务器端。现在服务器基本上就是nginx和srs两种,网上搜了下有个PingOS  已经实现nginx支持H265的RTMP  直接下载下来 参考说明文件编译即可 

github地址如下 

GitHub - pingostack/pingos: Based on the NGINX/RTMP/HTTP-FLV/HTTP-TS/HLS/HLS+/DASH/H.264/H.265/AAC/MP3/Live/Record/VOD/Push/Pull/Multiple Processes/Dynamic Configuration/Configuration Variables/Console Interface/Notify

加速连接 mirrors / pingostack / pingos · CODE CHINA (gitcode.net)

下载完如下操作 即可 

./release.sh -i

# 启动服务
cd /usr/local/pingos/
./sbin/nginx

由于我的服务器端都是装在虚拟机上的 后来测试发现,nginx的话,正常推流过程中 我把虚拟机suspend挂起 注意不是关机 ,过一段时间再打开,发现推流虽然正常 但是 流不能正常播放。

查看logs目录下的error.log会打印live:already publishing 网上搜了下说要做如下修改

(借用另一位博主的图片)

加上这个so_keepalive 但是我试了没有用 不知道为啥  但是srs就不会

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第3张图片

 后来就尝试srs 需要修改srs源码 以便于支持h265的rmtp 我用的版本是4.0 差别应该不大 

修改就两个文件 一个是 srs_kernel_codec.cpp  和srs_kernel_codec.hpp 

头文件增加如下定义 

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第4张图片

 cpp中修改如下 

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第5张图片

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第6张图片

  RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第7张图片

 很简单这样就可以了 

3.播放端 。网上搜了很多关于rmpt支持h265的文章 播放端基本上都是说要用大牛的播放器 

由于大牛的播放器在github  我下了四五次 每次下载的大小都不一样 ,最后 加速站点下下来,发现有1个多G  ,之前 github直接下的时候 有的 几十MB 有的时候100多MB 反正每次提示成功 但是大小都不一样 。

我下下来之后 反正 不能用  无论是 推流那个exe  还是播放器那个exe 都不能用 ,后来顺着软件上的联系方式 加了QQ群 ,说是要 付费的 具体我也不太清楚原因 ,总之 大牛的播放器 这条路失败。

然后不知道怎么想的 还是 搜什么搜到的 发现 可以直接修改FFMpeg 源码 ,测试发现可行 。

当然过程肯定会遇到各种坑 。下面 我就直接贴修改的地方吧  我的FFMpeg版本是4.3.2

重要提示:ffplay需要SDL的支持,所以如果要编译出来ffplay 需要先安装或者编译SDL之后再进行此操作。另外这里编译出来的ffplay只能在ubuntu系统系播放,windows系统的话请参考我的另一边文章:

 windows下支持H265的rtmp ffmpeg播放器 ffmpeg的编译_baoecit的博客-CSDN博客

回归正题

首先 ffmpeg下建一个脚本build.sh什么的 (我有时候需要编译arm版本,这样便于管理)

比如 arm版本我会这么写

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第8张图片

 ubuntu修改版本我会这么写(enable-rtmp_h265 是我自己为了给修改的地方增加宏自己定义的)

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第9张图片

 修改方式为打开configure文件。找到CONFIG_LIST关键字 添加自己定义的名字 如下图

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第10张图片

保存 之后 配置的时候添加 --enable-rtmp_h265  或者--disable-rtmp_h265

执行build.sh脚本之后可以去ffbuild目录下查看 我的就是如下了  之后可以在代码里面使用这个宏就可以 

 RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第11张图片

 涉及到修改的文件如下  flv.h flvdec.c flvenc.c

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第12张图片

 头文件修改的地方 增加

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第13张图片

 flvdec.c文件修改如下

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第14张图片

flv_set_video_codec函数

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第15张图片

 flv_read_packet函数

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第16张图片

 接下来是flvenc.c文件 

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第17张图片

 flv_write_codec_header函数修改如下

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第18张图片

 RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第19张图片

flv_write_trailer函数修改如下:

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第20张图片

 接下来是flv_write_packet函数

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第21张图片

  RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第22张图片

 RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第23张图片

 修改完毕 直接 编译就可以 没问题的话 生成的ffmpeg 就可以推送 支持h265rtmp ffplay用来播放

由于推送端我使用3531板子来做的 所以我只需要ffplay就可以

看下结果吧 :可以发现 stream video 那里的编码已经是hevc了说明正常 

RTMP 推送H265的实现(推流端、服务器、播放端)ffmpeg 播放H265_第24张图片

你可能感兴趣的:(海思平台开发,QMCY,FFMpeg,服务器,音视频,p2p,ffmpeg,rtmp)