废话不多说,先上实际测试时延,左侧用大牛直播SDK的Windows平台RTMP直播推送模块,采集毫秒计数器窗体,推RTMP到nginx服务器,右侧unity的播放器,播放RTMP流,同时四路播放,延迟如下:
系统由三个核心模块构成:
功能列表:
PlayerInstance
类是多实例播放器的核心组件,负责管理单个播放实例的生命周期,包括视频播放、录制、停止等操作。通过调用NTSmartPlayerSDK
提供的接口,实现了对视频流的解码、渲染和录制功能。
StartPlay
方法初始化播放器并开始播放指定的视频流。在播放过程中,会通过回调函数OnVideoFrame
获取视频帧数据,并将其渲染到Unity的Texture2D
对象上,实现视频的显示。同时,还支持硬件解码功能,提高了播放性能。
StartRecorder
方法实现,可以将播放的视频流录制到本地文件中。录制过程中,会根据设置的参数(如文件大小、文件名规则等)进行录制,并通过回调函数OnRecordEvent
通知录制状态。
PlayerInstance
类中,通过调用NTSmartPlayerSDK
的NT_SP_IsSupportH264HardwareDecoder
和NT_SP_IsSupportH265HardwareDecoder
方法,检测系统是否支持H.264和H.265的硬件解码功能。
NT_SP_SetH264HardwareDecoder
和NT_SP_SetH265HardwareDecoder
方法启用硬件解码功能。硬件解码可以利用GPU的计算能力,减少CPU的负担,从而提高视频播放的流畅度和性能。
PlayerManager
类是多实例播放器的管理核心,负责创建、管理和销毁播放实例。它通过一个字典player_instances_
来存储和管理所有的播放实例,每个实例都有一个唯一的ID标识。
CreatePlayer
方法根据传入的URL和ID创建一个新的PlayerInstance
对象,并将其添加到字典中。同时,会为每个播放实例分配一个独立的材质对象,用于视频的渲染。
PlayerManager
类会在应用退出时调用OnApplicationQuit
方法,释放所有的播放实例资源,确保系统的资源得到合理回收。
PlayerManager
类还负责管理播放实例的生命周期,包括播放、停止、录制等操作。在Update
方法中,会遍历所有的播放实例,调用它们的UpdateFrame
方法,更新每个播放实例的视频帧。
PlayerManager
类还处理播放实例的事件,如连接状态、缓冲状态等。通过回调函数OnEvent
,可以获取播放实例的事件信息,并根据事件类型进行相应的处理,如更新UI显示、记录日志等。
UIController
类负责处理用户界面的交互逻辑,为用户提供播放、录制、停止等操作的入口。通过在Unity编辑器中定义按钮、输入框等UI组件,并将它们与UIController
类的属性进行绑定,实现了用户界面的交互功能。
TogglePlay
和ToggleRecord
方法,实现了播放和录制的切换逻辑。当用户点击播放按钮时,会根据当前播放状态调用PlayerInstance
类的StartPlay
或StopPlay
方法,同时更新按钮的文本显示。录制操作的逻辑类似,通过调用StartRecorder
和StopRecorder
方法实现录制的开始和停止。
UIController
类会对输入的URL进行验证,确保其符合RTSP或RTMP协议的格式。通过IsRtspOrRtmp
方法,对输入的URL进行检查,如果不符合要求,则会提示用户输入无效的URL。
UIController
类会通过日志记录错误信息,并提示用户。这种错误处理机制可以及时发现和解决问题,提高应用的稳定性和用户体验。
PlayerInstance
类的Dispose
方法中,调用了ClearTextures
方法,释放了yTexture_
、uTexture_
和vTexture_
等纹理对象。同时,在PlayerManager
类的DestroyPlayer
方法中,也会调用Dispose
方法,确保在播放实例被销毁时,相关的资源得到及时释放。
PlayerInstance
类的ProcessVideoFrame
方法中,通过预先分配足够大小的内存空间,避免了在处理每一帧视频数据时都进行内存分配。
PlayerInstance
类中,可以通过创建一个单独的线程,专门用于处理视频帧数据。在OnVideoFrame
回调函数中,将获取到的视频帧数据放入一个线程安全的队列中,然后在单独的线程中从队列中取出数据进行处理和渲染。
PlayerInstance
类的StartPlay
方法中,可以通过异步调用NTSmartPlayerSDK
的接口来加载视频流的元数据。在加载过程中,可以通过回调函数获取加载进度,并将其更新到UI界面上,让用户了解当前的加载状态。
PlayerManager
类中定义一个全局的音量变量,并在每个播放实例中设置一个音量回调函数。当用户调整音量时,通过回调函数将新的音量值传递给每个播放实例,实现音量的同步调整。
PlayerInstance
类中,通过回调函数OnEvent
和OnRecordEvent
,可以获取播放实例的事件信息,并将其传递给PlayerManager
类。PlayerManager
类根据事件类型进行相应的处理,并将事件信息传递给UIController
类,以便更新用户界面。
PlayerInstance
类会通过回调函数通知PlayerManager
类,PlayerManager
类再将错误信息传递给UIController
类,UIController
类根据错误信息更新UI界面,提示用户发生错误。通过这种方式,可以实现播放实例与用户界面之间的高效交互,提高用户体验。
通过PlayerManager
动态创建/销毁实例,关键代码如下:
/*
* PlayerManager.cs
* Created by daniusdk.com
* WeChat: xinsheng120
*/
public PlayerInstance CreatePlayer(int id, string url) {
var player = new PlayerInstance(id);
player.SetUrl(url);
player_instances_.Add(id, player);
return player;
}
硬件解码优化:
StartPlay()
中检测硬件解码能力:
is_support_h264_hardware_decoder_ = NT_SP_IsSupportH264HardwareDecoder();
NTSmartPlayerSDK.NT_SP_SetH264HardwareDecoder(player_handle_, is_support ? 1 : 0, 0);
视频流通常采用YUV420格式,需转换为Unity支持的RGB材质。实现要点:
纹理初始化:
// PlayerInstance.cs
yTexture_ = new Texture2D(y_stride, h, TextureFormat.Alpha8, false, true);
target_material_.SetTexture("_NT_SDK_Y", yTexture_); // 绑定到Shader
跨步复制优化: 当源数据步长(Stride)与目标纹理不一致时,逐行复制内存:
// CopyFramePlane函数
for (int i = 0; i < lines; ++i) {
Marshal.Copy(src, d_plane, dst_index, d_stride);
src = IntPtr.Add(src, s_stride); // 按源步长移动指针
}
通过Native SDK回调监听连接、缓冲等事件:
// 事件回调处理
private void ProcessSDKEvent(UInt32 event_id, Int64 param1...) {
if (event_id == NT_SP_E_EVENT_ID_CONNECTED) {
Debug.Log("连接成功");
} else if (event_id == NT_SP_E_EVENT_ID_BUFFERING) {
buffer_percent_ = (Int32)param1; // 更新缓冲进度
}
}
支持音视频录制与文件管理:
NTSmartPlayerSDK.NT_SP_SetRecorderDirectoryW(player_handle_, "D:\\Rec");
NTSmartPlayerSDK.NT_SP_SetRecorderAudioTranscodeAAC(handle_, 1); // 转码为AAC
IDisposable
确保Native资源(如player_handle_
)及时释放。
lock (frame_lock_)
避免多线程帧数据竞争。
LoadRawTextureData
直接操作纹理内存,避免中间转换。
play_buffer_time_
调整缓冲阈值,平衡延迟与卡顿。
本文实现了一个高性能Unity多实例播放器,关键技术包括硬件解码、YUV处理和异步事件管理,毫秒级延迟,可以满足大多数低延迟场景诉求。
随着人工智能技术的发展,在集成大牛直播SDK的Unity的RTSP|RTMP播放模块的时候,后续可以在播放器中引入智能播放和推荐功能。例如,通过分析用户的观看历史和偏好,为用户推荐相关的视频内容,提高用户的观看体验。智能播放功能可以根据用户的操作习惯和偏好,自动调整播放器的参数,如播放速度、音量等。例如,如果用户经常观看快节奏的视频内容,播放器可以自动提高播放速度,以满足用户的需求。同时,还可以通过机器学习算法,对视频内容进行分析和分类,为用户提供更加精准的推荐。例如,根据视频的主题、风格等因素,为用户推荐相关的视频内容。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。