FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址

《FFmpeg开发实战:从零基础到短视频上线》一书在第10章介绍了轻量级流媒体服务器MediaMTX,通过该工具可以测试RTSP/RTMP等流媒体协议的推拉流。不过MediaMTX的功能实在是太简单了,无法应用于真实直播的生产环境,真正能用于生产环境的流媒体服务器还要看SRS或者ZLMediaKit。

SRS是一款开源流媒体服务器,最开始是做RTMP直播的,那时全称为"Simple RTMP Server",意思是简单的RTMP服务器。后来SRS增加支持了其他流媒体协议,包括HLS、SRT、WebRTC等等,它的全称又改为"Simple Realtime Server",意思是简单的实时服务器。
有关SRS的编译、安装与启动过程参见之前的文章《Linux环境安装SRS实现视频推流》。注意,使用ffmpeg命令把视频文件推流给SRS时,要注意区分FFmpeg的版本,因为FFmpeg从6.1开始才给RTMP协议支持HEVC、VP9、AV1这三种视频编码器,所以FFmpeg 6.0和更早的版本只能以H.264格式向SRS推流,如下所示:

复制代码
ffmpeg -re -stream_loop -1 -i "/usr/local/src/test/2018s.mp4" -vcodec h264 -f flv rtmp://127.0.0.1/live/test

而下面这种以HEVC格式(即H.265)向SRS推流的命令对于FFmpeg 6.0和更早的版本来说是错误的:

复制代码
ffmpeg -re -stream_loop -1 -i "/usr/local/src/test/2018s.mp4" -vcodec hevc -f flv rtmp://127.0.0.1/live/test

只有把FFmpeg升级到6.1或更高版本,才能以HEVC格式把视频文件推流给SRS。

在手机上可通过APP或者小程序播放RTMP直播流,其中小程序使用video标签播放RTMP链接,APP除了借助FFmpeg库处理之外,还能使用ExoPlayer播放RTMP链接。引入ExoPlayer播放RTMP直播流的集成步骤说明如下。

一、修改build.gradle

打开APP模块的build.gradle,在dependencies节点内部补充以下的导包配置:

复制代码
implementation 'com.google.android.exoplayer:exoplayer:2.17.1'
implementation 'com.google.android.exoplayer:extension-rtmp:2.17.1'

可见以上配置不但导入了exoplayer的主包,还导入了rtmp的扩展包。

二、修改播放代码支持RTMP流

ExoPlayer的详细用法参见《Android Studio开发实战:从零基础到App上线(第3版)》一书第14章的"14.3.3 新型播放器ExoPlayer",其中与RTMP有关的播放代码方法修改如下:

复制代码
// 播放视频
private void playVideo(String url) {
    DataSource.Factory factory = new DefaultDataSource.Factory(this);
    // 创建指定地址的媒体对象
    MediaItem videoItem = new MediaItem.Builder().setUri(Uri.parse(url)).build();
    // 基于工厂对象和媒体对象创建媒体来源
    MediaSource videoSource;
    if (url.endsWith("m3u8")) {  // HLS地址
        videoSource = new HlsMediaSource.Factory(factory)
                .createMediaSource(videoItem);
    } else if (url.startsWith("rtmp")) {  // RTMP地址
        videoSource = new ProgressiveMediaSource.Factory(new RtmpDataSource.Factory())
                .createMediaSource(videoItem);
    } else {
        videoSource = new ProgressiveMediaSource.Factory(factory)
                .createMediaSource(videoItem);
    }
    mPlayer.setMediaSource(videoSource); // 设置播放器的媒体来源
    mPlayer.prepare(); // 播放器准备就绪
    mPlayer.play(); // 播放器开始播放
}

可见主要改动是增加判断RTMP地址,如果是RTMP链接就引入RtmpDataSource作为数据工厂来源。

三、调整SRS的配置文件

通过小程序或者ExoPlayer播放RTMP直播流时,可能出现播放界面黑屏,但有声音传出的情况。这是因为SRS默认没有缓存关键帧,使得拉流一开始没找到关键帧就黑屏了。

解决办法是修改SRS配置,指定开启缓存GOP,这样客户端在拉流时总能找到已缓存的关键帧。打开srs安装目录下的conf/srs.conf,在"vhost defaultVhost"节点内部添加下面一行:

复制代码
gop_cache   on;

该行配置的作用是开启缓存关键帧,实际应用记得设置为on,否则客户端拉流找不到关键帧就无法渲染画面。

更多详细的FFmpeg开发知识参见《FFmpeg开发实战:从零基础到短视频上线》一书。

相关推荐
aqi0030 分钟前
FFmpeg开发笔记(六十四)使用国产的RedPlayer播放器观看网络视频
android·ffmpeg·音视频·直播·流媒体
英英_14 小时前
视频爬虫的Python库
开发语言·python·音视频
道剑剑非道16 小时前
QT开发技术【ffmpeg + QAudioOutput】音乐播放器 完善
开发语言·qt·ffmpeg
毒果16 小时前
FFmpeg 低延迟同屏方案
ffmpeg·同屏
weixin_5275504016 小时前
Linux 环境下高效视频切帧的实用指南
linux·运维·音视频
ai产品老杨17 小时前
减少交通拥堵、提高效率、改善交通安全的智慧交通开源了。
前端·vue.js·算法·ecmascript·音视频
红米饭配南瓜汤19 小时前
WebRTC中的几个Rtp*Sender
网络·网络协议·音视频·webrtc·媒体
EasyDSS1 天前
EasyRTC嵌入式音视频通信SDK助力物联网/视频物联网音视频打造全场景应用
人工智能·音视频
aqi001 天前
FFmpeg开发笔记(六十三)FFmpeg使用vvenc把视频转为H.266编码
ffmpeg·音视频·直播·流媒体
babytiger1 天前
rk3588 上运行smolvlm-realtime-webcam,将视频转为文字描述
音视频