使用EasyPusher实现移动端RTSP直播推流
EasyPusher是一款强大的国产移动端直播推流工具,特别适合实现RTSP直播推流。下面将详细介绍如何在Android平台上使用EasyPusher实现RTSP直播功能。
一、整体架构设计
二、环境准备
1. 添加依赖
在项目的build.gradle中添加依赖:
dependencies {
implementation 'com.github.easyPusher:easyPusher-android:2.5.0'
implementation 'com.github.easyPusher:rtsp-client:1.3.0'
}
2. 权限配置
在AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
三、核心代码实现
1. 初始化EasyPusher
public class RTSPLiveActivity extends AppCompatActivity {
private EasyPusher easyPusher;
private CameraHelper cameraHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live);
// 初始化EasyPusher
easyPusher = new EasyPusher.Builder()
.setContext(this)
.setVideoConfig(new VideoConfig()
.setResolution(Resolution.HD_720P)
.setFrameRate(30)
.setBitrate(2000) // kbps
.setOrientation(Orientation.PORTRAIT))
.setAudioConfig(new AudioConfig()
.setSampleRate(44100)
.setChannelConfig(AudioConfig.CHANNEL_MONO)
.setBitrate(64)) // kbps
.setRtspConfig(new RtspConfig()
.setServerUrl("rtsp://your-server-ip:8554/live")
.setUsername("admin")
.setPassword("123456"))
.build();
}
}
2. 摄像头初始化
private void initCamera() {
cameraHelper = new CameraHelper(this, Camera.CameraInfo.CAMERA_FACING_BACK);
cameraHelper.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// 将视频帧发送给EasyPusher
easyPusher.pushVideoFrame(data);
}
});
// 设置预览视图
SurfaceView previewView = findViewById(R.id.preview_view);
cameraHelper.setPreviewDisplay(previewView.getHolder());
}
3. 音频采集
private void initAudio() {
AudioRecordHelper audioHelper = new AudioRecordHelper(
AudioConfig.SAMPLE_RATE_44_1K,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audioHelper.setAudioCallback(new AudioRecordHelper.AudioCallback() {
@Override
public void onAudioData(byte[] data, int size) {
// 将音频数据发送给EasyPusher
easyPusher.pushAudioFrame(data, size);
}
});
}
4. 启动/停止推流
// 启动推流
public void startStreaming() {
if (checkPermissions()) {
cameraHelper.startPreview();
audioHelper.startRecording();
easyPusher.startStream();
}
}
// 停止推流
public void stopStreaming() {
cameraHelper.stopPreview();
audioHelper.stopRecording();
easyPusher.stopStream();
}
四、RTSP服务器配置
1. 使用MediaMTX作为RTSP服务器
# mediamtx.yml 配置文件
rtsp:
enabled: true
listenAddress: ":8554"
readTimeout: 10s
writeTimeout: 10s
paths:
live:
source: publisher
sourceOnDemand: true
runOnInit: ffmpeg -i - -c copy /recordings/$RTSP_PATH/$RTSP_PATH_$YYYY$MM$DD-$HH$MM$SS.mp4
2. 启动服务器
./mediamtx mediamtx.yml
五、高级功能实现
1. 网络自适应
public class NetworkAdaptor {
public void adjustBitrate(int currentBitrate, int packetLossRate) {
if (packetLossRate > 15) {
// 高丢包率,降低码率
int newBitrate = (int) (currentBitrate * 0.7);
easyPusher.setVideoBitrate(Math.max(800, newBitrate));
} else if (packetLossRate < 5) {
// 网络良好,提高码率
int newBitrate = (int) (currentBitrate * 1.2);
easyPusher.setVideoBitrate(Math.min(4000, newBitrate));
}
}
}
2. 视频滤镜处理
// 添加美颜滤镜
easyPusher.addVideoFilter(new BeautyFilter(context));
// 自定义滤镜实现
public class BeautyFilter implements VideoFilter {
@Override
public byte[] processFrame(byte[] frame, int width, int height) {
// 使用OpenGL或RenderScript实现美颜效果
return processBeautyEffect(frame, width, height);
}
}
3. 推流状态监控
easyPusher.setStreamStateListener(new StreamStateListener() {
@Override
public void onConnected() {
runOnUiThread(() -> showToast("RTSP连接成功"));
}
@Override
public void onDisconnected() {
runOnUiThread(() -> showToast("RTSP连接断开"));
}
@Override
public void onError(ErrorCode errorCode) {
runOnUiThread(() -> showToast("错误: " + errorCode.name()));
}
@Override
public void onStatistics(StreamStats stats) {
Log.d("RTSP Stats", "帧率: " + stats.getFps() +
", 码率: " + stats.getBitrate() + "kbps");
}
});
六、播放端实现
1. Android播放器
public class RtspPlayerActivity extends AppCompatActivity {
private VideoView videoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
videoView = findViewById(R.id.video_view);
videoView.setVideoPath("rtsp://server-ip:8554/live");
videoView.setOnPreparedListener(mp -> mp.start());
}
}
2. VLC播放器
rtsp://server-ip:8554/live
3. FFplay命令行播放
ffplay -rtsp_transport tcp rtsp://server-ip:8554/live
七、企业级功能扩展
1. 安全认证
// 设置RTSP认证
easyPusher.setRtspConfig(new RtspConfig()
.setServerUrl("rtsp://your-server-ip:8554/live")
.setUsername("admin")
.setPassword("securePassword123")
.setAuthType(RtspConfig.AUTH_DIGEST));
2. 推流加密
// 启用SRTP加密
easyPusher.enableEncryption(true);
easyPusher.setEncryptionKey("your-encryption-key");
3. 多路推流
// 同时推送到多个服务器
easyPusher.addRtspEndpoint(new RtspConfig()
.setServerUrl("rtsp://backup-server:8554/live")
.setUsername("backup")
.setPassword("backup123"));
八、性能优化策略
1. 硬件加速编码
// 启用硬件编码
easyPusher.setVideoConfig(new VideoConfig()
.setEncoderType(EncoderType.HARDWARE) // 使用硬件编码器
.setCodec(Codec.H264)); // 或H265
2. 功耗控制
public class PowerSaver {
public void enterLowPowerMode() {
// 降低帧率
easyPusher.setFrameRate(15);
// 降低分辨率
easyPusher.setResolution(Resolution.SD_480P);
// 关闭非必要功能
easyPusher.disableBeautyFilter();
}
}
3. 自适应分辨率
// 根据网络状态调整分辨率
public void adjustResolution(NetworkQuality quality) {
switch (quality) {
case EXCELLENT:
easyPusher.setResolution(Resolution.HD_1080P);
break;
case GOOD:
easyPusher.setResolution(Resolution.HD_720P);
break;
case POOR:
easyPusher.setResolution(Resolution.SD_480P);
break;
}
}
九、完整示例代码
1. 主活动实现
public class MainActivity extends AppCompatActivity {
private EasyPusher easyPusher;
private CameraHelper cameraHelper;
private AudioRecordHelper audioHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化UI
Button startBtn = findViewById(R.id.btn_start);
Button stopBtn = findViewById(R.id.btn_stop);
SurfaceView previewView = findViewById(R.id.preview_view);
// 初始化EasyPusher
easyPusher = new EasyPusher.Builder()
.setContext(this)
.setVideoConfig(new VideoConfig()
.setResolution(Resolution.HD_720P)
.setFrameRate(30)
.setBitrate(2000))
.setAudioConfig(new AudioConfig()
.setSampleRate(44100)
.setBitrate(64))
.setRtspConfig(new RtspConfig()
.setServerUrl("rtsp://192.168.1.100:8554/live")
.setUsername("admin")
.setPassword("123456"))
.build();
// 初始化摄像头
cameraHelper = new CameraHelper(this, Camera.CameraInfo.CAMERA_FACING_BACK);
cameraHelper.setPreviewDisplay(previewView.getHolder());
cameraHelper.setPreviewCallback(data -> easyPusher.pushVideoFrame(data));
// 初始化音频
audioHelper = new AudioRecordHelper(44100,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audioHelper.setAudioCallback((data, size) -> easyPusher.pushAudioFrame(data, size));
// 按钮事件
startBtn.setOnClickListener(v -> startStreaming());
stopBtn.setOnClickListener(v -> stopStreaming());
}
private void startStreaming() {
if (checkPermissions()) {
cameraHelper.startPreview();
audioHelper.startRecording();
easyPusher.startStream();
}
}
private void stopStreaming() {
cameraHelper.stopPreview();
audioHelper.stopRecording();
easyPusher.stopStream();
}
@Override
protected void onDestroy() {
super.onDestroy();
easyPusher.release();
}
}
2. 布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/preview_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<Button
android:id="@+id/btn_start"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="开始推流" />
<Button
android:id="@+id/btn_stop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止推流" />
</LinearLayout>
</RelativeLayout>
十、常见问题解决
1. 连接失败问题排查
问题 | 排查步骤 | 解决方案 |
---|---|---|
无法连接服务器 | 1. 检查服务器地址 2. 验证端口开放 3. 测试网络连通性 | 使用telnet测试端口 |
认证失败 | 1. 检查用户名密码 2. 验证认证类型 | 使用Wireshark抓包分析 |
视频黑屏 | 1. 检查摄像头权限 2. 验证预览是否正常 3. 检查编码格式 | 尝试软编码模式 |
无声音 | 1. 检查麦克风权限 2. 验证音频采样参数 | 调整音频配置 |
2. 性能优化建议
- 分辨率选择:根据网络状况动态调整
- 帧率控制:24-30fps之间最佳
- 编码参数:使用H.264 baseline profile
- 网络缓冲:设置合理缓冲区大小
- 硬件加速:优先使用硬件编码器
总结
通过EasyPusher实现移动端RTSP直播推流具有以下优势:
- 低延迟:RTSP协议支持<500ms端到端延迟
- 高兼容性:广泛兼容各类RTSP播放器
- 硬件加速:充分利用移动设备硬件编码能力
- 网络适应:智能码率控制适应不同网络环境
- 安全可靠:支持多种认证和加密方式
典型应用场景:
- 安防监控移动端推流
- 移动新闻直播系统
- 远程医疗实时会诊
- 工业巡检现场直播
- 教育直播课堂
通过本方案,您可以快速构建稳定高效的移动端RTSP直播系统,满足各种实时视频传输需求。