APP访问SRS推流的RTMP直播地址完整指南
在移动APP中访问SRS服务器推流的RTMP直播地址,需要完成以下关键步骤,下面提供详细的实现方案:
一、整体流程概述
二、APP端集成RTMP播放器
1. Android平台播放器选择
推荐方案:
-
ExoPlayer + RTMP扩展
// build.gradle implementation 'com.google.android.exoplayer:exoplayer-core:2.18.1' implementation 'com.google.android.exoplayer:exoplayer-ui:2.18.1' implementation 'com.github.arthenica:mobile-ffmpeg:4.4.LTS' // RTMP支持
-
ijkplayer (基于FFmpeg)
implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
播放器初始化代码:
// ExoPlayer示例
SimpleExoPlayer player = new SimpleExoPlayer.Builder(context).build();
playerView.setPlayer(player);
// 创建RTMP数据源
MediaItem mediaItem = new MediaItem.Builder()
.setUri("rtmp://your-server-ip/live/stream-name")
.setMimeType(MimeTypes.APPLICATION_RTMP)
.build();
player.setMediaItem(mediaItem);
player.prepare();
player.play();
2. iOS平台播放器选择
推荐方案:
-
IJKPlayer (推荐)
// Podfile pod 'IJKMediaFramework'
-
FFmpeg + 自定义播放器
播放器初始化代码:
// IJKPlayer示例
let player = IJKFFMoviePlayerController(contentURL: URL(string: "rtmp://your-server-ip/live/stream-name"), with: nil)!
player.view.frame = view.bounds
view.addSubview(player.view)
player.prepareToPlay()
player.play()
三、获取RTMP播放地址
SRS服务器RTMP地址格式:
rtmp://<服务器IP或域名>/<应用名>/<流名称>
示例:
rtmp://192.168.1.100/live/demo_stream
地址动态获取方式:
1. 固定地址(开发测试)
// Android
String rtmpUrl = "rtmp://192.168.1.100/live/demo_stream";
2. API动态获取(生产环境)
// 从后端API获取直播地址
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://your-api-server/")
.build();
LiveStreamService service = retrofit.create(LiveStreamService.class);
Call<StreamInfo> call = service.getLiveStreamInfo(streamId);
call.enqueue(new Callback<StreamInfo>() {
@Override
public void onResponse(Call<StreamInfo> call, Response<StreamInfo> response) {
if (response.isSuccessful()) {
String rtmpUrl = response.body().getRtmpUrl();
startPlayback(rtmpUrl);
}
}
});
四、播放器配置与优化
1. 关键配置参数
// ExoPlayer 配置示例
DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
.setBufferDurationsMs(
5000, // minBufferMs
10000, // maxBufferMs
1500, // bufferForPlaybackMs
2000 // bufferForPlaybackAfterRebufferMs
)
.build();
ExoPlayer player = new ExoPlayer.Builder(context)
.setLoadControl(loadControl)
.setTrackSelector(new DefaultTrackSelector(context))
.build();
2. 低延迟优化
// 启用低延迟模式
trackSelector.setParameters(
trackSelector.buildUponParameters()
.setMaxVideoSizeSd()
.setForceLowestBitrate(true)
);
3. 网络状态处理
// 监听网络变化
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
connectivityManager.registerNetworkCallback(
new NetworkRequest.Builder().build(),
new ConnectivityManager.NetworkCallback() {
@Override
public void onLost(Network network) {
player.pause();
}
@Override
public void onAvailable(Network network) {
player.play();
}
}
);
五、安全与鉴权
1. URL鉴权方案
rtmp://server/live/stream?token=SECRET_KEY&expire=1672531200
2. APP端鉴权实现
String generateSecureUrl(String streamName) {
long expireTime = System.currentTimeMillis() / 1000 + 3600; // 1小时有效
String token = HmacSHA256("SECRET_KEY", streamName + expireTime);
return "rtmp://server/live/" + streamName +
"?token=" + token +
"&expire=" + expireTime;
}
3. SRS服务器鉴权配置
vhost __defaultVhost__ {
security {
enabled on;
allow play 192.168.0.0/16; # 允许内网播放
deny play all;
}
}
六、备选播放方案
1. HTTP-FLV播放(推荐备选)
http://server:8080/live/stream.flv
2. HLS播放(兼容性最好)
http://server:8080/live/stream.m3u8
3. WebRTC播放(超低延迟)
webrtc://server/live/stream
七、调试与问题排查
常见问题解决方案:
问题现象 | 排查步骤 | 解决方案 |
---|---|---|
黑屏无画面 | 1. 检查播放地址 2. 网络抓包 3. 查看SRS日志 | 确保流已推送,检查防火墙设置 |
高延迟(>3秒) | 1. 检查播放器缓冲设置 2. 网络延迟测试 | 减小播放器缓冲区,启用低延迟模式 |
频繁卡顿 | 1. 检查网络带宽 2. 查看SRS服务器负载 | 降低推流码率,开启SRS缓存优化 |
音画不同步 | 1. 检查时间戳 2. 查看编解码参数 | 统一音视频时间基准,调整播放器同步阈值 |
调试工具:
- SRS控制台:
http://server:8080
- 网络抓包:Wireshark过滤RTMP流量
- 播放器日志:开启详细日志模式
- 性能监控:SRS API
http://server:1985/api/v1/streams
八、高级功能实现
1. 多码率自适应
# SRS配置多码率转码
vhost __defaultVhost__ {
transcode {
enabled on;
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
engine hd {
enabled on;
vcodec libx264;
vbitrate 1500;
vfps 25;
vwidth 1280;
vheight 720;
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_hd;
}
engine sd {
enabled on;
vcodec libx264;
vbitrate 800;
vfps 25;
vwidth 854;
vheight 480;
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_sd;
}
}
}
2. 播放器多码率切换
// ExoPlayer多码率切换
TrackSelectionParameters params = player.getTrackSelectionParameters();
player.setTrackSelectionParameters(
params.buildUpon()
.setMaxVideoSize(1280, 720) // 选择HD流
.build()
);
3. 实时消息互动
// 通过WebSocket与SRS交互
WebSocket webSocket = new WebSocket("ws://server:8080/live/stream");
webSocket.send("chat:Hello from APP!");
九、性能优化建议
1. 播放器优化
- 启用硬件解码
- 设置合理的缓冲区大小
- 使用预加载机制
2. 网络优化
- 开启QUIC协议支持
- 实现自适应码率切换
- 使用CDN加速分发
3. 服务器优化
# SRS性能优化配置
listen 1935;
max_connections 1000;
daemon on;
srs_log_tank file;
srs_log_file ./objs/srs.log;
pid ./objs/srs.pid;
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
http_api {
enabled on;
listen 1985;
}
vhost __defaultVhost__ {
min_latency on;
tcp_nodelay on;
}
十、完整示例代码
Android完整播放器实现
public class LivePlayerActivity extends AppCompatActivity {
private SimpleExoPlayer player;
private PlayerView playerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
// 初始化播放器
playerView = findViewById(R.id.player_view);
initializePlayer();
// 获取播放地址
String streamId = getIntent().getStringExtra("STREAM_ID");
String rtmpUrl = "rtmp://your-server/live/" + streamId;
// 开始播放
startPlayback(rtmpUrl);
}
private void initializePlayer() {
// 创建低延迟播放器
DefaultTrackSelector trackSelector = new DefaultTrackSelector(this);
trackSelector.setParameters(
trackSelector.buildUponParameters()
.setMaxVideoSize(1280, 720)
.setPreferredTextLanguage("zh")
);
DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
.setBufferDurationsMs(3000, 5000, 1000, 2000)
.build();
player = new ExoPlayer.Builder(this)
.setTrackSelector(trackSelector)
.setLoadControl(loadControl)
.build();
playerView.setPlayer(player);
}
private void startPlayback(String url) {
MediaItem mediaItem = new MediaItem.Builder()
.setUri(url)
.setMimeType(MimeTypes.APPLICATION_RTMP)
.build();
player.setMediaItem(mediaItem);
player.prepare();
player.play();
}
@Override
protected void onDestroy() {
super.onDestroy();
player.release();
}
}
总结
在APP中访问SRS的RTMP直播流,核心要点包括:
- 播放器集成:选择成熟的播放器框架(ExoPlayer/IJKPlayer)
- 地址获取:动态从API获取播放地址
- 安全机制:实现URL鉴权和访问控制
- 性能优化:配置低延迟播放参数
- 备选方案:支持HTTP-FLV/HLS作为备选协议
- 监控调试:使用SRS控制台和网络工具排查问题
对于生产环境,建议:
- 使用HTTPS获取播放地址
- 实现动态鉴权机制
- 开启SRS的集群部署
- 添加CDN分发支持
- 实施全面的监控告警系统
通过以上方案,APP可以高效、稳定地访问SRS推流的RTMP直播内容,提供流畅的直播观看体验。