news 2026/5/21 22:13:17

大牛直播SDK(SmartMediaKit)Android Unity3D 播放器集成文档

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大牛直播SDK(SmartMediaKit)Android Unity3D 播放器集成文档

目标平台:Android(API 21+)
支持协议:RTSP、RTMP


目录

  1. 概述
  2. 环境要求
  3. 工程文件说明
  4. 快速集成步骤
  5. PlayerConfig 配置说明
  6. 核心 API 说明
  7. 事件回调说明
  8. 录像功能
  9. 视频渲染原理

1. 概述

本文档描述如何在 Android Unity3D 工程中集成大牛直播 SDK,实现 RTSP / RTMP 直播流的拉取、渲染与本地录像功能。

架构总览

帧渲染模型(PULL)

SDK 不主动推送帧数据,而是由 Unity 主线程每帧主动调用GetVideoFrame()拉取,避免跨线程写纹理的问题:

2. 环境要求

项目要求
Unity2019.4.13f1 或更高
Android API最低 21(Android 5.0),推荐 26+
构建工具IL2CPP 或 Mono 均可
权限INTERNETWRITE_EXTERNAL_STORAGE(录像)、READ_EXTERNAL_STORAGE

AndroidManifest.xml 权限

<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="28"/><uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"android:maxSdkVersion="32"/>

Android 10+ 录像路径建议使用Application.persistentDataPath,无需存储权限。


3. 工程文件说明

各文件职责

文件职责是否需要修改
NTSmartPlayerAPI.csJNI 接口定义,1:1 对应 Java 层❌ 通常不改
NTPlayerEvent.cs事件 ID 常量,对应NTSmartEventID.java❌ 不改
NTPlayerWrapper.cs句柄管理、状态机、配置下发⚠️ 如需扩展参数可改
PlayerConfig.cs序列化配置字段,Inspector 可调✅ 按需扩展
PlayerInstance.cs事件处理、YUV 渲染、状态文本✅ 按需扩展
PlayerManager.cs场景入口,SDK 初始化⚠️ 一般不改
UIController.cs业务 UI 逻辑✅ 按需修改

4. 快速集成步骤

Step 1 — 拷贝 SDK 文件

将大牛直播提供的以下文件放入工程对应目录:

Step 2 — 拷贝 C# 脚本

将本工程Assets/目录下的所有.cs文件拷贝到目标工程。

Step 3 — 配置 Player Settings

Edit → Project Settings → Player → Android:

设置项推荐值
Minimum API LevelAndroid 5.0 (API 21)
Scripting BackendIL2CPP(发布)/ Mono(调试)
Target ArchitectureARM64(必选)、ARMv7(可选)
Internet AccessRequired
Write PermissionExternal (SDCard)(如需 sdcard 录像)

Step 4 — 搭建场景 | 接线 Inspector

Step 5 — 授权 SDK

PlayerManager.Awake()初始化后调用:

NTSmartPlayerAPI.NT_U3D_SetSDKClientKey("your_cid","your_key",0);

或在PlayerConfig扩展字段统一管理。


Step 6. PlayerConfig 配置说明

PlayerManagerGameObject 上通过 Inspector 配置,也可在代码中访问PlayerManager.Instance.config

[Serializable]publicclassPlayerConfig{// ── 解码 ──────────────────────────────────────────────────────────────publicboolenableHardwareDecoder=false;// false = 软解(兼容性好);true = 硬解(性能好,需设备支持)// 运行中不可切换,需停止播放后修改再重新开始// ── 缓冲 ──────────────────────────────────────────────────────────────[Range(0,8000)]publicintbufferTimeMs=0;// 0 = 最低延迟模式;建议直播设 0,点播/不稳定网络设 500~2000// ── RTSP 传输 ──────────────────────────────────────────────────────────publicboolrtspUseTcp=false;// false = 优先 UDP,丢包时考虑改 true[Range(1,30)]publicintrtspTimeoutSec=10;// 连接超时(秒)publicboolrtspAutoSwitchTcpUdp=true;// UDP 失败自动切 TCP// ── 音频 ──────────────────────────────────────────────────────────────publicboolmute=false;[Range(0,100)]publicintvolume=100;publicbooluseAudioTrack=true;// true = AudioTrack 模式(推荐)// ── 播放行为 ──────────────────────────────────────────────────────────publicboolfastStartup=true;// 减少起播黑屏时间publicboollowLatencyMode=false;// 超低延迟,会增加丢帧概率[Range(0,270)]publicintrotateDegrees=0;// 顺时针旋转:0/90/180/270// ── 录像 ──────────────────────────────────────────────────────────────publicintrecMaxFileSizeMB=500;// 单个录像文件最大体积(MB),超过后自动切片}

6. 核心 API 说明

6.1 播放控制(通过 UIController 或直接调用)

// 创建播放器实例(内部调用 NT_U3D_Open + ApplyConfig)PlayerInstanceplayer=PlayerManager.Instance.CreatePlayer("rtsp://...");// 绑定渲染目标(必须在 StartPlay 前调用)player.SetRenderTarget(rawImage,matI420,matNV21,matNV12);// 开始播放player.StartPlay();// 停止播放player.StopPlay();// 销毁播放器(Close 句柄 + 释放纹理)PlayerManager.Instance.DestroyPlayer();

6.2 实时控制(播放中随时可调)

// 静音 / 取消静音player.SetMuteRealtime(true);// 调节音量(0–100)player.SetVolumeRealtime(80);

6.3 录像控制

// 开始录像(目录路径,SDK 自动创建)player.StartRecorder("/sdcard/daniulive/Record");// 或使用 persistentDataPath(Android 10+ 推荐,无需权限)player.StartRecorder(Application.persistentDataPath+"/Record");// 停止录像player.StopRecorder();// 查询状态boolisRecording=player.is_recording;

6.4 状态查询

boolisPlaying=player.is_playing;boolisRecording=player.is_recording;longhandle=player.handle;// 0 = 未初始化intwidth=player.VideoWidth;intheight=player.VideoHeight;stringstatus=player.StatusText;// 格式化状态文本,直接显示给用户

7. 事件回调说明

事件由 SDK 通过UnitySendMessage发到PlayerManager.onNTSmartEvent,再分发到PlayerInstance.HandleEvent()

消息格式(逗号分隔):

handle,code,param1,param2,param3,param4

所有事件 ID 定义在NTPlayerEvent.cs,与 Android SDK 的NTSmartEventID.java完全对应。

事件列表

常量说明参数
STARTED0x1000001SDK 内部状态机已启动
CONNECTING0x1000002连接中
CONNECTION_FAILED0x1000003连接失败
CONNECTED0x1000004已连接,即将收到视频
DISCONNECTED0x1000005连接断开
STOP0x1000006SDK 内部停止(如断流)
RESOLUTION_INFO0x1000007视频分辨率p1=width, p2=height
NO_MEDIADATA0x1000008长时间收不到媒体数据
SWITCH_URL0x1000009正在切换 URL
CAPTURE_IMAGE0x100000A快照结果p1=0 成功,非0 失败
RTSP_STATUS_CODE0x100000BRTSP 状态码上报p1=状态码(如 401)
RECORDER_NEW_FILE0x1000021录像开始写入新文件p3=完整文件路径
RECORDER_FILE_DONE0x1000022一个录像文件写完p3=完整文件路径
START_BUFFERING0x1000081开始缓冲
BUFFERING0x1000082缓冲中p1=进度百分比(0–100)
STOP_BUFFERING0x1000083缓冲结束,恢复播放
DOWNLOAD_SPEED0x1000091下载速度上报见下方说明

DOWNLOAD_SPEED 参数解析

p1 = 下载速度(Byte/s) p2 = 丢包率编码(long): bit31=1 → 高 15 位为前向丢包率 FLR(Q8.8 定点,÷256 得比例) bit15=1 → 低 15 位为综合丢包率 LR(Q8.8 定点,÷256 得比例)

示例解析(已在PlayerInstance.HandleEvent中实现):

// 转换为百分比floatflr=((loss>>16)&0x7FFF)/256.0f*100f;// 前向丢包率 %floatlr=(loss&0x7FFF)/256.0f*100f;// 综合丢包率 %

8. 录像功能

录像流程

StartRecorder(dir) ├─ NT_U3D_CreateFileDirectory(dir) ← 创建目录 ├─ NT_U3D_SetRecorderDirectory(handle, dir) ├─ NT_U3D_SetRecorderFileMaxSize(handle, MB) ├─ NT_U3D_SetRecorderAudioTranscodeAAC(handle, 1) ← 音频转 AAC(重要) └─ NT_U3D_StartRecorder(handle) └─ 触发 RECORDER_NEW_FILE 事件(p3 = 文件路径)

录像与播放的关系

  • 录像和播放共享同一个 SDK 句柄,可以同时进行
  • 单独录像(不播放):理论上支持,但建议同时启动播放保证视频数据正常拉取
  • 停止播放时,若录像仍在进行,录像不会中断

文件切片

recMaxFileSizeMB(默认 500MB)达到后 SDK 自动切片:

  • 触发RECORDER_FILE_DONE(旧文件写完)
  • 触发RECORDER_NEW_FILE(新文件开始)

录像路径建议

// Android 10+ 推荐,无需存储权限stringdir=Path.Combine(Application.persistentDataPath,"Record");// 对应路径:/data/data/<包名>/files/Record 或// /sdcard/Android/data/<包名>/files/Record(外部存储)// 旧版 Android(≤9)可用 sdcard 路径,需权限stringdir="/sdcard/daniulive/Record";

9. 视频渲染原理

帧格式

常量格式使用场景
FORMAT_I4203YUV 4:2:0 Planar软解默认输出
FORMAT_NV214YUV 4:2:0 Semi-Planar(VU 交错)硬解常见
FORMAT_NV125YUV 4:2:0 Semi-Planar(UV 交错)硬解常见

纹理结构

I420(三平面):

yTex_: Texture2D(stride0, height, Alpha8) ← Y 分量 uTex_: Texture2D(stride1, height/2, Alpha8) ← U 分量 vTex_: Texture2D(stride2, height/2, Alpha8) ← V 分量

NV21 / NV12(双平面):

yTex_: Texture2D(stride0, height, Alpha8) ← Y 分量 uTex_: Texture2D(width/2, height/2, RG16) ← UV 交错分量

Shader 属性

Shader 通过以下属性名接收纹理:

_NT_SDK_Y ← Y 纹理 _NT_SDK_U ← U(或 UV)纹理 _NT_SDK_V ← V 纹理(仅 I420 格式使用)

注意:Shader 和 Material 由大牛直播 SDK 提供,不要修改。


附录 A:事件回调格式参考

SDK 通过UnitySendMessage发出的原始消息格式:

"handle,code,param1,param2,param3,param4"

PlayerManager.onNTSmartEvent()中解析:

string[]parts=msg.Split(',');// parts[0] = handle(long,多播放器时用于路由)// parts[1] = code(int,事件 ID)// parts[2] = param1// parts[3] = param2// parts[4] = param3(录像事件中为文件路径)// parts[5] = param4(目前未使用)

附录 B:调用时序图

播放时序

UIController.OnPlayClicked() → PlayerManager.CreatePlayer(url) → PlayerInstance.Open(url, config, goName) → NTPlayerWrapper.Open() → NT_U3D_Open() ← 获取句柄 → NT_U3D_Set_Game_Object() ← 注册事件接收对象 → ApplyConfig() ← 一次性下发所有参数 → PlayerInstance.SetRenderTarget(...) ← 绑定渲染目标 → PlayerInstance.StartPlay() → NTPlayerWrapper.StartPlay() → NT_U3D_StartPlay() ← 开始拉流 每帧: PlayerManager.Update() → PlayerInstance.UpdateFrame() → NT_U3D_GetVideoFrame() ← 拉帧 → UploadTextures() ← 上传 YUV 纹理 事件: SDK → UnitySendMessage("PlayerManager", "onNTSmartEvent", msg) → PlayerInstance.HandleEvent(code, p1, p2, p3)

停止时序

UIController.OnPlayClicked()(再次点击) → PlayerInstance.StopPlay() → NTPlayerWrapper.StopPlay() → NT_U3D_StopPlay() → UIController.ClearRenderView() → 若 !is_recording → PlayerManager.DestroyPlayer() → PlayerInstance.Close() → NTPlayerWrapper.Close() → NT_U3D_StopPlay() (幂等,已停则跳过) → NT_U3D_StopRecorder() (幂等) → NT_U3D_Close() → DisposeTextures()

📎 CSDN官方博客:音视频牛哥-CSDN博客

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 22:07:12

巨亏47亿,市值5000亿:拆解智谱AI的定价逻辑

2026年1月8日&#xff0c;智谱以每股116.2港元登陆港交所。截至5月中旬&#xff0c;其股价一度冲上1160港元&#xff0c;市值突破5000亿港元&#xff0c;较发行价累涨近10倍。而同期披露的2025年财报显示&#xff0c;公司全年营收7.24亿元&#xff0c;经调整净亏损31.82亿元。来…

作者头像 李华
网站建设 2026/5/21 22:06:38

亲测新加坡家具物流优质公司分享

在新加坡家具物流领域&#xff0c;捷晟物流是较为优质的选择。以下为你详细介绍相关内容。服务模式多样捷晟物流提供海运和空运两种服务模式。海运方面&#xff0c;有整柜&#xff08;FCL&#xff09;与拼货&#xff08;LCL&#xff09;两种选择。对于批量较大的家具运输&#…

作者头像 李华
网站建设 2026/5/21 22:00:43

双榜第一!文心5.1登顶中文创意写作综合实力评测

【大力财经】5月18日&#xff0c;全球权威ICT领域市场研究机构Omdia发布《2026 年基础模型中文创意写作能力评估》报告&#xff0c;围绕中文创意写作七大核心维度&#xff0c;对 DeepSeek V4、文心5.1&#xff08;ERNIE 5.1&#xff09;、GPT 5.5 等 8大国内外主流顶级文本模型…

作者头像 李华