
在移动端音视频领域,单纯的 RTMP 推流已不再是技术天花板。真正的挑战在于:如何在资源受限的 Android 设备上,构建一个既能“对外”进行 RTMP 直播、又能“对内”提供低延迟 RTSP 分发,同时还能完成“本地”高保真录像的『全功能媒体节点』?
面对这一需求,传统的串行处理模式往往会导致 CPU 负载过高、画面卡顿甚至 OOM。本文将深入源码,结合 MainActivity.java 及核心辅助类,剖析如何利用 Android Camera2 API 的高效采集能力,配合 大牛直播SDK (SmartPublisher) 的多路分发架构,打造一套集采集、编码、推流、服务、存储于一体的高可靠、低延迟音视频解决方案。

在提供的源码中,MainActivity 充当了控制中心的角色,而核心的音视频处理逻辑被封装在 LibPublisherWrapper 和 SmartPublisherJniV2 中。整体数据流向如下:
Camera2Helper 负责调用 Camera2 API,通过 ImageReader 获取 YUV_420_888 格式的视频帧。
LayerPostThread 负责处理视频层叠加(如时间戳、文字水印、图片Logo)。
SmartPublisherJniV2 (Native层) 接收处理后的YUV数据,进行H.264/H.265编码,并同时分发给:
这种架构的优势在于一次采集、一次编码、多路复用,极大地降低了CPU和内存的开销。
Camera2 API 相比旧版 Camera API 提供了更强大的控制力,但也更为复杂。源码中的 Camera2Helper.java 封装了繁琐的 Session 创建和 Surface 配置。
在 MainActivity 中,实现了 Camera2Listener 接口。核心数据回调在 onCameraImageData 方法中:
@Override
public void onCameraImageData(Image image) {
// 校验格式是否为 YUV_420_888
if (image.getFormat() != ImageFormat.YUV_420_888) {
return;
}
Image.Plane[] planes = image.getPlanes();
// 获取 Y, U, V 平面的 Buffer 及 Stride 信息
// ... (省略部分裁剪代码)
// 处理设备旋转角度
int rotation_degree = cameraImageRotationDegree_;
if (rotation_degree < 0) return;
// 将数据投递给 SDK
for (LibPublisherWrapper i : publisher_array_)
i.PostLayerImageYUV420888ByteBuffer(0, 0, 0,
planes[0].getBuffer(), y_offset, planes[0].getRowStride(),
planes[1].getBuffer(), u_offset, planes[1].getRowStride(),
planes[2].getBuffer(), v_offset, planes[2].getRowStride(), planes[1].getPixelStride(),
w, h, 0, 0,
scale_w, scale_h, scale_filter_mode, rotation_degree);
}
技术解读:
Image.Plane 的 ByteBuffer 传递给 Native 层(PostLayerImageYUV420888ByteBuffer),避免了在 Java 层进行大量的数据拷贝,这是降低延迟和 CPU 占用的关键。
stream_publisher_ 和 snap_shot_publisher_,意味着同一份 YUV 数据被同时用于推流/录像和快照处理。
为了保证多线程环境下的稳定性(UI线程操作开关,采集线程投递数据,编码线程处理数据),源码封装了 LibPublisherWrapper 类。它通过 ReentrantReadWriteLock 读写锁来保证 SDK 句柄的安全访问。
public class LibPublisherWrapper implements AutoCloseable {
private final ReadWriteLock rw_lock_ = new ReentrantReadWriteLock(true);
// ...
public boolean PostLayerImageYUV420888ByteBuffer(...) {
if (!check_native_handle()) return false;
if (!read_lock_.tryLock()) return false; // 尝试获取读锁,避免阻塞采集线程
try {
return OK == lib_publisher_.PostLayerImageYUV420888ByteBuffer(get(), ...);
} finally {
read_lock_.unlock();
}
}
}
这种 Wrapper 模式在音视频开发中非常推荐,能有效防止在 SDK 销毁过程中(如切换摄像头或关闭 Activity)因数据投递造成的 Crash。
这是大牛直播SDK的一大特色。传统的推流端通常只负责推流,拉流需要依赖 Nginx 或 SRS 等服务器。但该 SDK 允许 Android 设备变身为 RTSP 服务器。
在 MainActivity 中:
// 初始化 RTSP Server 上下文
LibPublisherWrapper.RTSPServer.initialize_sdk(libPublisher, context_);
// 启动服务
int port = 8554;
LibPublisherWrapper.RTSPServer.Handle server_handle =
LibPublisherWrapper.RTSPServer.create_and_start_server(libPublisher, port, user_name, password);
// 将 RTSP Server 关联到 Publisher
stream_publisher_.AddRtspStreamServer(rtsp_server_.get_native());
应用场景:
rtsp://device_ip:8554/stream1 拉取低延迟流,无需经过云端 CDN,延迟可控制在毫秒级。
源码中包含一个 LayerPostThread.java,它展示了 SDK 强大的视频层叠加能力。
makeTimestampString() 生成当前时间 Bitmap。
这些图层并不是在 Java 层通过 Canvas 绘制到视频 Bitmap 上(那样效率太低),而是生成 Overlay 数据后,通过 PostLayerBitmap 或 PostLayerImageRGBA8888ByteBuffer 传递给底层,由 GPU 或 Native 高效混合。
// LayerPostThread.java 核心循环
private void on_run() {
while(!is_exit()) {
// 更新时间戳图层
post_timestamp_layer(...);
// 更新文字图层
postText1Layer(...);
// ...
sleep_ms(update_interval);
}
}
stream_publisher_.StartRecorder() 即可开启本地录像。SDK 内部处理了音视频同步和 MP4 封装,且支持设置文件分片大小(SetRecorderFileMaxSize)。
EventHandlerPublisherV2 监听 SDK 回调。例如 EVENT_DANIULIVE_ERC_PUBLISHER_DISCONNECTED 事件触发时,应用层可以进行 UI 提示或自动重连逻辑。
通过分析这份代码,我们可以总结出几个关键的性能优化点:
initialize_publisher 方法中优先尝试开启 H.264/H.265 硬编码 (SetSmartPublisherVideoHWEncoder),大幅降低 CPU 占用。
纵观这份 Demo 源码,我们看到的不仅仅是一个功能的堆砌,而是一套经得起生产环境考验的 Android 音视频架构范本。它展示了大牛直播 SDK 如何在复杂的 Android 碎片化生态中,提供一种“确定性”的解决方案:
LibPublisherWrapper 的封装不仅仅是为了代码整洁,更体现了生命周期管理的智慧。通过引入 ReentrantReadWriteLock(读写锁)和 WeakReference(弱引用),这套架构巧妙地解决了音视频开发中最为棘手的“高并发数据竞争”与“对象引用泄漏”问题。它确保了在 Activity 销毁、摄像头切换或网络抖动等极端情况下,底层 Native 资源依然能被安全、有序地释放,这是从“Demo”走向“商用产品”的关键一步。
Camera2Helper 实现了一次 YUV 数据采集,却能同时支撑 RTMP 远端直播、RTSP 局域网分发 以及 MP4 本地存证 三大业务流。这种“单源多汇”的 pipeline 设计,最大程度地复用了编码前的 YUV 数据和编码后的 H.264/H.265 数据,避免了重复的内存拷贝与色彩空间转换,将 CPU 和内存的开销压到了极致。
对于广大音视频开发者而言,不仅是一把打开 RTMP/RTSP 协议大门的钥匙,更是一份关于高性能、低延迟、高稳定性音视频应用开发的最佳实践指南。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。