适用版本:HarmonyOS NEXT(API 12+)
语言栈:ArkTS + C++ NDK(NAPI)
核心文件:SmartPlayerTypes.ets/SmartPlayerWrapper.ets/SmartPlayerNative.ets/SmartPlayerPage.ets
一、概述
大牛直播 SDK(SmartMediaKit)是一套跨平台、低延迟、高稳定性的音视频拉流播放库,已在Windows、Linux、Android、iOS 上被广泛应用于直播监控、视频会议、工业物联等场景。本文档面向鸿蒙 NEXT(纯血鸿蒙)平台,介绍如何将 libSmartPlayer.so 集成到 ArkTS 工程中,实现 RTSP / RTMP 流的全功能播放。
1.1 主要特性
特性
说明
协议支持
RTMP、RTSP(TCP/UDP 自动切换)
解码模式
软解码/ 硬解码/ 硬解码+Surface直通
低延迟模式
可配置缓冲为 0ms,实现亚秒级延迟
渲染方式
EGL/GLES 硬件渲染(XComponent)或 RGBA 软渲染回调
录像
边播边录,支持分片、音频转码 AAC,多路同时录制
图像处理
旋转、翻转、亮度/对比度/饱和度实时调节
数据回调
视频帧(RGBA_8888)、H.264 SEI 用户数据
截图
JPEG/PNG,可异步保存至本地
1.2 架构层次
┌──────────────────────────────────────────────────┐
│ SmartPlayerPage.ets │ ← UI 层 / 生命周期管理
├──────────────────────────────────────────────────┤
│ SmartPlayerWrapper.ets │ ← ArkTS 业务封装层
│ SmartPlayerTypes.ets │ ← 公共类型 / 枚举 / 接口定义
├──────────────────────────────────────────────────┤
│ SmartPlayerNative.ets │ ← NAPI 桥接层(直接调用 .so)
├──────────────────────────────────────────────────┤
│ libSmartPlayer.so (C++ NDK 核心) │ ← 原生播放引擎
│ OhosEglRender / OHAudio / XComponent Surface │
└──────────────────────────────────────────────────┘
二、工程配置
2.1 目录结构
entry/
├── src/main/
│ ├── ets/
│ │ ├── media/
│ │ │ ├── SmartPlayerTypes.ets # 公共类型定义
│ │ │ ├── SmartPlayerNative.ets # NAPI 桥接
│ │ │ ├── SmartPlayerWrapper.ets # 封装层
│ │ │ ├── PlayerSnapshotHelper.ets # 截图辅助
│ │ │ └── PlayerRecorderHelper.ets # 录像辅助
│ │ ├── pages/
│ │ │ └── SmartPlayerPage.ets # 播放页面
│ └── libs/
│ ├── arm64-v8a/
│ │ └── libSmartPlayer.so
│ └── x86_64/ # 模拟器调试
│ └── libSmartPlayer.so
2.2 module.json5 权限声明
{
"module": {
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" },
{ "name": "ohos.permission.READ_MEDIA" },
{ "name": "ohos.permission.WRITE_MEDIA" }
]
}
}
三、核心类型与接口说明
3.1 事件枚举(SmartPlayerEvent)
播放器所有异步状态变化均通过事件回调上报,枚举值与 C++ 层 nt_event_define.h 完全一致:
事件
值
含义
CONNECTING
0x01000002
正在连接服务器
CONNECTED
0x01000004
TCP/UDP 连接已建立
STARTED
0x01000001
音视频解码已启动,画面开始输出
CONNECTION_FAILED
0x01000003
连接失败(网络不通、地址错误)
DISCONNECTED
0x01000005
连接已断开(服务端主动断流)
STOP
0x01000006
播放已停止
RESOLUTION_INFO
0x01000007
分辨率信息(param1=宽, param2=高)
NO_MEDIADATA_RECEIVED
0x01000008
连接成功但长时间无媒体数据
START_BUFFERING
0x01000081
进入缓冲等待
BUFFERING
0x01000082
缓冲进度(param1=百分比)
STOP_BUFFERING
0x01000083
缓冲结束,恢复播放
DOWNLOAD_SPEED
0x01000091
下载速度上报(param1=Bps)
RECORDER_START_NEW_FILE
0x01000021
开始录制新分片文件(strParam=路径)
RECORDER_FILE_FINISHED
0x01000022
分片文件录制完成(strParam=路径)
SWITCH_URL
0x01000009
URL 切换完成
CAPTURE_IMAGE
0x0100000A
截图完成(param1=0 成功)
四、集成步骤详解
4.1 第一步:初始化播放器
播放器实例通过 open() 创建,内部调用 NAPI 层的 SmartPlayerOpen(),成功后返回一个正整数句柄(handle)。一个 Page 对应一个 Wrapper 实例,跨页面保活通过 detach()/attach() 机制实现。
// 在 aboutToAppear 或首次播放前调用
const ok = this.player.open();
if (!ok) {
console.error('SmartPlayer open 失败,native 库可能未加载');
return;
}
常见问题:
open()失败通常是因为libSmartPlayer.so未正确加载,检查 CMakeLists 的IMPORTED_LOCATION路径和 ABI 是否匹配。
4.2 第二步:注册事件回调
必须在 startPlayback() 之前注册事件回调,否则会丢失 CONNECTING、CONNECTED 等早期事件:
this.player.setEventCallback((eventId, param1, param2, strParam) => {
switch (eventId) {
case SmartPlayerEvent.STARTED:
this.statusText = '播放中';
break;
case SmartPlayerEvent.RESOLUTION_INFO:
this.resolutionText = `${param1}x${param2}`;
break;
case SmartPlayerEvent.CONNECTION_FAILED:
this.statusText = '连接失败,请检查网络或地址';
break;
case SmartPlayerEvent.DOWNLOAD_SPEED:
// param1 单位为 Bps,转 KB/s 显示
this.speedText = `${Math.round(param1 / 1024)} KB/s`;
break;
case SmartPlayerEvent.DISCONNECTED:
this.statusText = '已断开,尝试重连...';
// 可在此触发自动重连逻辑
break;
}
});
注意:回调在 Native 线程触发,切勿在回调内做耗时操作。需要更新 UI 时,ArkTS 的
@State赋值会自动切换到 UI 线程,无需手动runOnUIThread。
4.3 第三步:绑定渲染 Surface
鸿蒙 NEXT 使用 XComponent 作为视频渲染载体,必须在 XComponent.onLoad 回调中获取 surfaceId 并传递给 SDK:
// ArkTS 页面 build() 中声明 XComponent
XComponent({
id: 'smart_player_surface',
type: XComponentType.SURFACE,
libraryname: 'SmartPlayer', // 必须与 .so 模块名一致
controller: this.xComponentController
})
.onLoad(() => {
// surfaceId 是连接 ArkUI 与 Native EGL 渲染的唯一凭证
this.surfaceId = this.xComponentController.getXComponentSurfaceId();
// Surface 就绪后立即尝试恢复正在进行的播放会话
this.tryRecoverAfterSurfaceReady('XComponent onLoad');
})
.onDestroy(() => {
// Surface 销毁后清空 surfaceId,防止向已销毁 Surface 渲染
this.surfaceId = '';
})
.width('100%')
.height('100%')
然后通过 Wrapper 层下发:
const ok = this.player.setSurface(this.surfaceId);
if (!ok) {
console.error('setSurface 失败,surfaceId 可能为空或 XComponent 未就绪');
}
关键设计原则:
XComponent必须始终挂载在组件树中。
4.4 第四步:配置播放参数
所有播放参数必须在 startPlayback() 之前设置完毕,播放进行中修改部分参数(如 TCP 模式、缓冲时长)不会立即生效,需要停播后重新配置。
基础参数配置
// 设置播放地址
this.player.setUrl('rtsp://192.168.0.104:18554/stream1');
// 渲染 Surface(见第三步)
this.player.setSurface(this.surfaceId);
// 解码模式
// 0 = 软解码(兼容性最好,适合调试)
// 1 = 硬解码(H.264,推荐真机使用)
// 2 = 硬解码 + Surface 直通(最低延迟,需硬件支持)
this.player.setVideoHWDecoder(1);
// HEVC/H.265 硬解
this.player.setVideoHevcHWDecoder(1);
// 渲染缩放模式
// FILL = 铺满屏幕(可能拉伸变形)
// FIT = 等比例缩放(保持宽高比,可能出现黑边)
this.player.setRenderScaleMode(SmartPlayerRenderScaleMode.FIT);
RTSP 专项配置
// TCP 传输模式(网络质量差时推荐开启,默认 UDP)
this.player.setRTSPTcpMode(true);
// 自动切换 TCP/UDP(遭遇 UDP 丢包时自动回退到 TCP)
this.player.setRTSPAutoSwitchTcpUdp(true);
// RTSP 连接超时(秒)
this.player.setRTSPTimeout(10);
// RTSP 鉴权(需要认证的流)
this.player.setRTSPAuthenticationInfo('admin', 'password123');
延迟优化配置
// 低延迟模式:将内部缓冲压缩到最低(适合实时监控)
this.player.setLowLatencyMode(true);
// 低延迟模式开启时,缓冲时长应设为 0
this.player.setBuffer(0);
// 秒开优化:加速首帧显示(推荐始终开启)
this.player.setFastStartup(true);
// 常规直播场景(需要流畅但可接受 1-2 秒延迟)
this.player.setLowLatencyMode(false);
this.player.setBuffer(2000); // 2000ms 缓冲
下载速度上报
// 开启下载速度上报,每 1 秒触发一次 DOWNLOAD_SPEED 事件
this.player.setReportDownloadSpeed(true, 1);
4.5 第五步:启动播放
private doPlay(): void {
// 1. 打开播放器实例(如果还没打开)
if (!this.player.isOpened()) {
if (!this.player.open()) {
this.statusText = '初始化失败';
return;
}
}
// 2. 注册事件/视频回调
this.bindEventCallback();
this.bindVideoDataCallbackIfNeeded();
// 3. 下发播放参数(URL、Surface、解码器配置等)
this.player.setUrl(this.playUrl);
this.player.setSurface(this.surfaceId);
this.player.setVideoHWDecoder(this.useHardwareDecoder ? 1 : 0);
this.player.setRenderScaleMode(this.renderScaleMode);
this.player.setLowLatencyMode(this.isLowLatency);
this.player.setRTSPTcpMode(this.isTcpMode);
this.player.setFastStartup(this.isFastStartup);
this.player.setBuffer(this.bufferMs);
this.player.setReportDownloadSpeed(true, 1);
// 4. 启动播放
const ok = this.player.startPlayback();
if (!ok) {
this.statusText = '启动失败';
return;
}
this.statusText = '连接中...';
}
4.6 第六步:停止播放
private doStop(): void {
// 停止播放流
this.player.stopPlayback();
// 清理视频帧回调和软渲染器
this.player.setVideoDataCallback(null);
this.player.setSEIDataCallback(null);
this.softRendererCtrl.stop();
// 如果播放器不再处于任何活跃状态,则释放 native 资源
if (!this.player.isPlayingState() && !this.player.isRecordingState()) {
this.player.close();
}
this.statusText = '已停止';
}
五、解码模式详解
5.1 三种解码模式对比
模式
代码值
特点
适用场景
软解码
0
CPU 解码,兼容性最好,功耗较高
设备性能好,解码兼容性友好
硬解码
1
MediaCodec Surface,GPU 渲染,低功耗
真机直播/监控(推荐)
硬解+Surface直通
2
解码输出直接绑定 XComponent Surface,延迟最低
实时监控、低延迟场景
5.2 硬解开启方式
// H.264 硬解
this.player.setVideoHWDecoder(1);
// HEVC/H.265 硬解
this.player.setVideoHevcHWDecoder(1);
// Surface 直通模式(mode=2 时需同时开启内部 Surface 模式)
// 对应 NAPI 层 SetHardwareDecoderOutputInternalSurface(handle, 1)
this.player.setVideoDecoderMode(2);
注意:硬解码模式与视频帧数据回调(
setVideoDataCallback)互斥。开启硬解时,视频帧不会回调到 ArkTS 层,需要 AI 分析等场景必须使用软解码。
5.3 软渲染回调(模拟器 / AI 分析)
// 仅在 decodeMode === 0(软解码)时启用
this.player.setVideoDataCallback((width: number, height: number, data: ArrayBuffer) => {
// data 是 RGBA_8888 格式的原始像素数据
this.softRendererCtrl.onFrame(width, height, data);
// 扩展点:如需 AI 推理,每 N 帧取一次
if (this.frameCount % 5 === 0) {
this.doAIInference(width, height, data);
}
});
SoftRenderer 内部使用双缓冲 + PixelMap + Canvas.drawImage 实现零分配渲染,避免每帧 GC 压力:
// SoftRenderView 在 build() 中与 XComponent 叠加显示
Stack() {
XComponent({ ... })
.visibility(ENABLE_SOFT_RENDER && decodeMode === 0
? Visibility.Hidden : Visibility.Visible)
if (ENABLE_SOFT_RENDER && decodeMode === 0) {
SoftRenderView({ controller: this.softRendererCtrl })
.width('100%').height('100%')
}
}
HarmonyOS NEXT纯血鸿蒙RTSP|RTMP播放器
六、录像功能
6.1 录像配置与启动
录像功能不依赖于正在播放,可以纯录像(无画面预览):
// Step 1: 设置录像目录
const filesDir = getContext(this).filesDir;
const recordDir = `${filesDir}/recordings`;
this.player.createFileDirectory(recordDir);
this.player.setRecorderDirectory(recordDir);
// Step 2: 录像参数配置
this.player.setRecorderFileMaxSize(200); // 单文件最大 200MB 后自动分片
this.player.setRecorderAudioTranscodeAAC(true); // 音频转码为 AAC(兼容性好)
this.player.setRecorderVideo(true); // 录制视频流
this.player.setRecorderAudio(true); // 录制音频流
// Step 3: 开始录像(如果还未播放,需先 applyBaseConfig)
const ok = this.player.startRecorder();
if (!ok) {
console.error('录像启动失败');
}
6.2 录像事件处理
case SmartPlayerEvent.RECORDER_START_NEW_FILE:
// strParam 是新分片文件的完整路径
this.currentRecordingFile = strParam;
console.info(`开始录制新文件: ${strParam}`);
break;
case SmartPlayerEvent.RECORDER_FILE_FINISHED:
// strParam 是已完成文件的路径,可在此触发文件处理(上传、缩略图等)
this.lastFinishedFile = strParam;
console.info(`文件录制完成: ${strParam}`);
break;
6.3 停止录像
this.player.stopRecorder();
// 如果录像结束后也不需要继续播放,则释放资源
if (!this.player.isPlayingState()) {
this.player.close();
}
七、截图功能
7.1 触发截图
// 方式 1:截图保存到指定路径(JPEG)
const savePath = `${this.recordDir}/snapshot_${Date.now()}.jpg`;
this.player.captureImage(
0, // compressFormat: 0=JPEG, 1=PNG
90, // quality: 0~100
savePath,
'userData' // 透传参数,会在 CAPTURE_IMAGE 事件的 strParam 中返回
);
7.2 处理截图结果
截图是异步操作,完成后触发 CAPTURE_IMAGE 事件:
case SmartPlayerEvent.CAPTURE_IMAGE:
if (param1 === 0) {
// 截图成功,strParam 是保存路径
console.info(`截图已保存: ${strParam}`);
// 可在此触发分享/预览
} else {
console.error('截图失败');
}
break;
八、图像实时调节
以下调节支持在播放过程中实时生效,无需重启播放器:
8.1 亮度 / 对比度 / 饱和度
// 必须先开启对应调节功能,再设置值
// 值范围:-100 ~ 100,SDK 内部实际使用 0~100 区间(50 为中性值)
// 亮度调节
this.player.enableVideoBrightnessOption(true);
this.player.setVideoBrightness(60); // 50 为默认值,>50 变亮,<50 变暗
// 对比度调节
this.player.enableVideoContrastOption(true);
this.player.setVideoContrast(55);
// 饱和度调节
this.player.enableVideoSaturationOption(true);
this.player.setVideoSaturation(45); // <50 偏灰,>50 色彩浓郁
// 重置为默认值
this.player.setVideoBrightness(50);
this.player.setVideoContrast(50);
this.player.setVideoSaturation(50);
8.2 旋转与翻转
// 旋转(支持 0 / 90 / 180 / 270 度,播放中可实时切换)
this.player.setRotateDegrees(90);
// 水平翻转(镜像)
this.player.setFlipHorizontal(true);
// 垂直翻转(上下颠倒)
this.player.setFlipVertical(false);
8.3 音量控制
// 音量范围:0~100
this.player.setVolume(80);
// 静音(不影响音量设置值,恢复时无需重新设置音量)
this.player.setMute(true);
this.player.setMute(false);
纯血鸿蒙(HarmonyOS )RTSP直播播放器时延测试
九、SEI 数据回调(H.264 用户自定义数据)
H.264 SEI(Supplemental Enhancement Information)常用于在视频流中传递业务数据,如字幕时间码、AI 检测结果等。
this.player.setSEIDataCallback((type: number, pts: number, data: ArrayBuffer) => {
if (type === 0) {
// Unregistered User Data:业务自定义文本数据
const bytes = new Uint8Array(data);
const text = String.fromCharCode(...bytes).replace(/\0/g, '').trim();
console.info(`SEI UserData pts=${pts}ms: ${text}`);
} else if (type === 1) {
// 原始 SEI NALU 字节流,适合需要完整解析 SEI 结构的场景
console.info(`SEI Raw pts=${pts}ms, size=${data.byteLength}B`);
}
});
性能提示:SEI 回调与视频帧同频(每帧一次),建议在回调内加计数器限频,避免日志刷屏或 JS 压力过大。
十、完整播放页面示例
以下是一个完整最小化播放页面的代码骨架,涵盖核心生命周期:
@Entry
@Component
struct MinimalPlayerPage {
private player: SmartPlayerWrapper = new SmartPlayerWrapper();
private xCtrl: XComponentController = new XComponentController();
private surfaceId: string = '';
@State isPlaying: boolean = false;
@State statusText: string = '就绪';
@State playUrl: string = 'rtsp://192.168.0.104:18554/stream1';
build() {
Column({ space: 12 }) {
// 视频渲染区域
XComponent({
id: 'player_surface',
type: XComponentType.SURFACE,
libraryname: 'SmartPlayer',
controller: this.xCtrl
})
.onLoad(() => {
this.surfaceId = this.xCtrl.getXComponentSurfaceId();
// Surface 就绪后,如果播放器已在运行,重新绑定 Surface
if (this.player.isPlayingState()) {
this.player.setSurface(this.surfaceId);
}
})
.onDestroy(() => { this.surfaceId = ''; })
.width('100%')
.height(240)
// 状态文本
Text(this.statusText).fontSize(14).fontColor('#666666')
// URL 输入
TextInput({ text: this.playUrl })
.enabled(!this.isPlaying)
.onChange(v => { this.playUrl = v; })
// 播放控制
Button(this.isPlaying ? '停止' : '播放')
.onClick(() => { this.isPlaying ? this.doStop() : this.doPlay(); })
}
.width('100%').padding(16)
}
private doPlay(): void {
if (!this.player.isOpened()) this.player.open();
this.player.setEventCallback((eventId, p1, p2) => {
if (eventId === SmartPlayerEvent.STARTED) {
this.isPlaying = true;
this.statusText = '播放中';
} else if (eventId === SmartPlayerEvent.STOP) {
this.isPlaying = false;
this.statusText = '已停止';
} else if (eventId === SmartPlayerEvent.CONNECTION_FAILED) {
this.statusText = '连接失败';
} else if (eventId === SmartPlayerEvent.RESOLUTION_INFO) {
this.statusText = `播放中 ${p1}x${p2}`;
}
});
this.player.setUrl(this.playUrl);
this.player.setSurface(this.surfaceId);
this.player.setVideoHWDecoder(1);
this.player.setLowLatencyMode(true);
this.player.setFastStartup(true);
this.player.startPlayback();
this.statusText = '连接中...';
}
private doStop(): void {
this.player.stopPlayback();
this.isPlaying = false;
this.statusText = '已停止';
}
aboutToDisappear(): void {
if (this.player.isPlayingState()) {
this.player.detach();
} else {
this.player.close();
}
}
}
十一、常见问题排查
11.1 画面黑屏(无图像输出)
可能原因
排查方法
surfaceId 为空
确认 XComponent.onLoad 已触发,打印 surfaceId 检查
setSurface 未在播放前调用
检查参数下发顺序,确保 setSurface 早于 startPlayback
11.2 连接失败
可能原因
排查方法
无网络权限
检查 module.json5 中的 ohos.permission.INTERNET
RTSP UDP 被防火墙拦截
开启 TCP 模式:setRTSPTcpMode(true)
地址格式错误
RTSP 格式:rtsp://ip:port/path,RTMP:rtmp://ip:port/app/stream
服务器需要鉴权
调用 setRTSPAuthenticationInfo(user, password)
RTSP 连接超时
默认超时可能偏短,尝试 setRTSPTimeout(15)
11.3 .so 加载失败
Error: Failed to load module 'SmartPlayer'
- 检查
CMakeLists.txt中IMPORTED_LOCATION的 ABI 路径(arm64-v8a / x86_64) - 检查
module.json5中abilities.srcEntry的name字段 - 确认
.so文件已通过 DevEco Studio 的打包流程正确拷贝到 hap 包
十二、性能调优建议
12.1 延迟优化
// 极低延迟配置(适合实时监控,可接受偶尔卡顿)
player.setLowLatencyMode(true);
player.setBuffer(0);
player.setFastStartup(true);
player.setVideoHWDecoder(1); // 硬解降低解码延迟
player.setVideoDecoderMode(2); // Surface 直通,省去帧拷贝
// 流畅优先配置(适合直播回放,延迟 2~5 秒可接受)
player.setLowLatencyMode(false);
player.setBuffer(3000); // 3 秒缓冲,平滑网络抖动
12.2 多路播放
每个播放器实例对应一个独立的 SmartPlayerWrapper,多路播放时每路独立 open / setUrl / startPlayback,互不影响:
const player1 = new SmartPlayerWrapper();
const player2 = new SmartPlayerWrapper();
player1.open();
player2.open();
// 分别配置和启动...
附录 A:NAPI 接口速查表
NAPI 函数
Wrapper 方法
说明
SmartPlayerOpen()
open()
创建 native 实例,返回 handle
SmartPlayerClose(handle)
close()
释放 native 实例
SetSmartPlayerEventCallback
setEventCallback()
注册事件回调
SmartPlayerSetSurface
setSurface()
绑定渲染 Surface
SmartPlayerSetUrl
setUrl()
设置播放地址
SmartPlayerStartPlayback
startPlayback()
开始播放
SmartPlayerStopPlayback
stopPlayback()
停止播放
SmartPlayerSwitchPlaybackUrl
switchUrl()
无缝切换地址
SetSmartPlayerVideoHWDecoder
setVideoHWDecoder()
H.264 硬解开关
SetSmartPlayerVideoHevcHWDecoder
setVideoHevcHWDecoder()
HEVC 硬解开关
SmartPlayerSetBuffer
setBuffer()
缓冲时长(ms)
SmartPlayerSetLowLatencyMode
setLowLatencyMode()
低延迟模式
SmartPlayerSetFastStartup
setFastStartup()
秒开优化
SmartPlayerSetRTSPTcpMode
setRTSPTcpMode()
RTSP TCP 模式
SmartPlayerSetRTSPTimeout
setRTSPTimeout()
RTSP 超时(秒)
SmartPlayerSetRenderScaleMode
setRenderScaleMode()
渲染缩放模式
SmartPlayerSetRotateDegrees
setRotateDegrees()
旋转角度
SmartPlayerSetFlipHorizontal
setFlipHorizontal()
水平翻转
SmartPlayerSetFlipVertical
setFlipVertical()
垂直翻转
SmartPlayerEnableVideoBrightnessOption
enableVideoBrightnessOption()
亮度调节开关
SmartPlayerSetVideoBrightness
setVideoBrightness()
亮度值
SmartPlayerEnableVideoContrastOption
enableVideoContrastOption()
对比度调节开关
SmartPlayerSetVideoContrast
setVideoContrast()
对比度值
SmartPlayerEnableVideoSaturationOption
enableVideoSaturationOption()
饱和度调节开关
SmartPlayerSetVideoSaturation
setVideoSaturation()
饱和度值
SmartPlayerStartRecorder
startRecorder()
开始录像
SmartPlayerStopRecorder
stopRecorder()
停止录像
SmartPlayerCaptureImage
captureImage()
截图(异步)
SmartPlayerSetVideoDataCallback
setVideoDataCallback()
视频帧回调(RGBA)
SmartPlayerSetSEIDataCallback
setSEIDataCallback()
SEI 数据回调
附录 B:事件流转时序图
调用 startPlayback()
│
▼
[CONNECTING] ──── 建立 TCP/UDP 连接
│
▼
[CONNECTED] ──── 协议握手完成
│
▼
[START_BUFFERING] ──── 开始填充缓冲区(buffer > 0 时出现)
│
[BUFFERING 0%→100%] ── 缓冲进度(buffer > 0 时出现)
│
▼
[RESOLUTION_INFO] ──── 报告视频分辨率(param1=宽, param2=高)
│
▼
[STARTED] ──── 画面开始输出,播放正式开始
│
├── [DOWNLOAD_SPEED] ── 定期下载速度上报
├── [START_BUFFERING / BUFFERING / STOP_BUFFERING] ── 网络抖动时缓冲
│
▼(调用 stopPlayback 或断流)
[DISCONNECTED / STOP] ──── 播放结束
**备注:**本文档基于大牛直播 SDK(SmartMediaKit)鸿蒙 NEXT RTSP/RTMP直播播放器SDK,结合 SmartPlayerWrapper / SmartPlayerPage 实际代码整理。 如需获取 SDK 授权或技术支持,请联系大牛直播SDK官方渠道。