Unity下如何实现RTMP或RTSP播放端录像?

简介: Unity下如何实现RTMP或RTSP播放端录像?

好多开发者问我们,Unity环境下,除了RTSP或RTMP的播放,如果有录像诉求,怎么实现?实际上录像相对播放来说,更简单一些,因为不涉及到绘制,只要拉流下来数据,直接写mp4文件就好了。

本文以大牛直播SDK的Windows平台为例,大概介绍下如何实现Unity环境下的录制,Linux、Android、iOS平台实现也类似,都是原生接口,然后对接下就好:

unity播放器.png

开始录像

因为涉及到可能同时录制多路的场景(考虑到磁盘读写IO,Windows平台一般不建议多录录制),录像的话,需要考虑的是,设置好文件录制规则,比如,是否录制纯音频或纯视频、单个录制文件大小、文件录制目录等,并设置录像回调事件:

/** SmartPlayerWinMono.cs* Author: daniusdk.com*/privatevoidStartRecorder(intsel)
{
Debug.Log("StartRecorder++, sel: "+sel);
if (videoctrl[sel].is_recording_)
  {
Debug.Log("StartRecorder, already started.. sel: "+sel);
return;
  }
if (!videoctrl[sel].is_playing_)
  {
if (!OpenPlayerHandle(sel))
    {
Debug.LogError("call OpenPlayerHandle failed..");
return;
    }
  }
boolis_rec_video=true;
boolis_rec_audio=true;
NTSmartPlayerSDK.NT_SP_SetRecorderVideo(videoctrl[sel].player_handle_, is_rec_video?1 : 0);
NTSmartPlayerSDK.NT_SP_SetRecorderAudio(videoctrl[sel].player_handle_, is_rec_audio?1 : 0);
Stringrec_dir="D:\\Rec";     //录像目录可自行指定Stringrec_name_file_prefix_="daniu"+sel.ToString();
UInt32max_file_size=200*1024; // 单位是KByte, 默认200MBboolis_append_date=true;
boolis_append_time=true;
boolis_audio_transcode_aac=true;
UInt32ret=NTSmartPlayerSDK.NT_SP_SetRecorderDirectory(videoctrl[sel].player_handle_, rec_dir);
if (NT.NTBaseCodeDefine.NT_ERC_OK!=ret)
  {
Debug.LogError("设置录像目录失败,请确保目录存在且是英文目录");
return;
  }
NTSmartPlayerSDK.NT_SP_SetRecorderFileMaxSize(videoctrl[sel].player_handle_, max_file_size);
NT_SP_RecorderFileNameRulerrec_name_ruler=newNT_SP_RecorderFileNameRuler();
rec_name_ruler.type_=0;
rec_name_ruler.file_name_prefix_=rec_name_file_prefix_;
rec_name_ruler.append_date_=is_append_date?1 : 0;
rec_name_ruler.append_time_=is_append_time?1 : 0;
NTSmartPlayerSDK.NT_SP_SetRecorderFileNameRuler(videoctrl[sel].player_handle_, refrec_name_ruler);
NTSmartPlayerSDK.NT_SP_SetRecorderAudioTranscodeAAC(videoctrl[sel].player_handle_, is_audio_transcode_aac?1 : 0);
videoctrl[sel].record_call_back_=newSP_SDKRecorderCallBack(NT_SP_SDKRecorderCallBack);
NTSmartPlayerSDK.NT_SP_SetRecorderCallBack(videoctrl[sel].player_handle_, IntPtr.Zero, videoctrl[sel].record_call_back_);
videoctrl[sel].set_record_call_back_=newVideoControl.SetRecordCallBack(RecordCallBack);
if (NT.NTBaseCodeDefine.NT_ERC_OK!=NTSmartPlayerSDK.NT_SP_StartRecorder(videoctrl[sel].player_handle_))
  {
Debug.LogError("call NT_SP_StartRecorder failed..");
return;
  }
videoctrl[sel].is_recording_=true;
}

image.gif

其中OpenPlayerHandle()实现如下,通过调用Open()接口生成个player实例句柄,然后后续针对这个句柄操作即可,如果同一个实例句柄下需要播放,直接调用播放接口就好了。

privateboolOpenPlayerHandle(intsel)
{
if (videoctrl[sel].player_handle_!=IntPtr.Zero)
returntrue;
window_handle_=IntPtr.Zero;
if (videoctrl[sel].player_handle_==IntPtr.Zero)
  {
videoctrl[sel].player_handle_=newIntPtr();
UInt32ret_open=NTSmartPlayerSDK.NT_SP_Open(outvideoctrl[sel].player_handle_, window_handle_, 0, IntPtr.Zero);
if (ret_open!=0)
    {
videoctrl[sel].player_handle_=IntPtr.Zero;
Debug.LogError("call NT_SP_Open failed, sel: "+sel);
returnfalse;
    }
  }
videoctrl[sel].event_call_back_=newSP_SDKEventCallBack(NT_SP_SDKEventCallBack);
NTSmartPlayerSDK.NT_SP_SetEventCallBack(videoctrl[sel].player_handle_, window_handle_, videoctrl[sel].event_call_back_);
videoctrl[sel].sdk_event_call_back_=newVideoControl.SetEventCallBack(SDKEventCallBack);
if (IntPtr.Zero==videoctrl[sel].player_handle_)
returnfalse;
/* ++ 播放前参数配置可加在此处 ++ */intplay_buffer_time_=100;
NTSmartPlayerSDK.NT_SP_SetBuffer(videoctrl[sel].player_handle_, play_buffer_time_);                 //设置buffer timeintis_using_tcp=1;        //TCP模式NTSmartPlayerSDK.NT_SP_SetRTSPTcpMode(videoctrl[sel].player_handle_, is_using_tcp);
inttimeout=10;
NTSmartPlayerSDK.NT_SP_SetRtspTimeout(videoctrl[sel].player_handle_, timeout);
intis_auto_switch_tcp_udp=1;
NTSmartPlayerSDK.NT_SP_SetRtspAutoSwitchTcpUdp(videoctrl[sel].player_handle_, is_auto_switch_tcp_udp);
Booleanis_mute_=false;
NTSmartPlayerSDK.NT_SP_SetMute(videoctrl[sel].player_handle_, is_mute_?1 : 0);                    //是否启动播放的时候静音intis_fast_startup=1;
NTSmartPlayerSDK.NT_SP_SetFastStartup(videoctrl[sel].player_handle_, is_fast_startup);              //设置快速启动模式Booleanis_low_latency_=false;
NTSmartPlayerSDK.NT_SP_SetLowLatencyMode(videoctrl[sel].player_handle_, is_low_latency_?1 : 0);    //设置是否启用低延迟模式//设置旋转角度(设置0, 90, 180, 270度有效,其他值无效)introtate_degrees=0;
NTSmartPlayerSDK.NT_SP_SetRotation(videoctrl[sel].player_handle_, rotate_degrees);
intvolume=100;
NTSmartPlayerSDK.NT_SP_SetAudioVolume(videoctrl[sel].player_handle_, volume); //设置播放音量, 范围是[0, 100], 0是静音,100是最大音量, 默认是100// 设置上传下载报速度intis_report=0;
intreport_interval=2;
NTSmartPlayerSDK.NT_SP_SetReportDownloadSpeed(videoctrl[sel].player_handle_, is_report, report_interval);
//设置播放URLNTSmartPlayerSDK.NT_SP_SetURL(videoctrl[sel].player_handle_, videoctrl[sel].playback_url_);
/* -- 播放前参数配置可加在此处 -- */returntrue;
}

image.gif

录像回调事件如下:

publicvoidRecordCallBack(UInt32status, [MarshalAs(UnmanagedType.LPStr)] Stringfile_name, intsel)
{
if (status==1)    //status 1:表示开始写一个新录像文件  {
Debug.Log("RecordCallBack, 开始一个新的录像文件, sel: "+sel+" status: "+status+", filename: "+file_name);
  }
elseif (status==2)    //status 2:表示已经写好一个录像文件  {
Debug.Log("RecordCallBack, 已生成一个录像文件, sel: "+sel+" status: "+status+", filename: "+file_name);
  }
}

image.gif

停止录像

privatevoidStopRecorder(intsel)
{
Debug.Log("StopRecorder++, sel: "+sel);
if (videoctrl[sel].player_handle_==IntPtr.Zero)
  {
return;
  }
NTSmartPlayerSDK.NT_SP_StopRecorder(videoctrl[sel].player_handle_);
videoctrl[sel].is_recording_=false;
if (!videoctrl[sel].is_playing_)
  {
NTSmartPlayerSDK.NT_SP_Close(videoctrl[sel].player_handle_);
videoctrl[sel].player_handle_=IntPtr.Zero;
  }
}

image.gif

以上是Unity平台RTMP或RTSP播放端录像相关接口设计和调用实例,感兴趣的开发者可以参考。

相关文章
|
4月前
|
数据采集 编解码 图形学
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
Android平台Unity下如何通过WebCamTexture采集摄像头数据并推送至RTMP服务器或轻量级RTSP服务
115 0
|
8月前
|
编解码 数据处理 vr&ar
VR头显Unity下如何实现毫秒级延迟的RTMP或RTSP播放?
VR头显Unity下如何实现毫秒级延迟的RTMP或RTSP播放?
182 1
|
8月前
|
编解码 开发工具 图形学
Unity环境下RTMP推流+RTMP播放低延迟解决方案
在本文之前,我们发布了Unity环境下的RTMP推流(Windows平台+Android平台)和RTMP|RTSP拉流(Windows平台+Android平台+iOS平台)低延迟的解决方案,今天做个整体汇总,权当抛砖引玉。
451 0
|
8月前
|
编解码 监控 vr&ar
Unity3D下如何采集camera场景数据并推送RTMP服务?
Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下:
|
8月前
|
编解码 监控 图形学
Windows平台Unity下播放RTSP或RTMP如何开启硬解码?
我们在做Windows平台Unity播放RTMP或RTSP的时候,遇到这样的问题,比如展会、安防监控等场景下,需要同时播放多路RTMP或RTSP流,这样对设备性能,提出来更高的要求。
|
5月前
|
开发框架 Java C#
【Unity逆向】玩游戏遇到的“飞天锁血”是怎么实现的?
【Unity逆向】玩游戏遇到的“飞天锁血”是怎么实现的?
93 0
|
5月前
|
存储 自然语言处理 监控
【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换
Unity的多语言本地化是一个很实用的功能,它可以帮助游戏支持多种语言,让不同语言的玩家都能够更好地体验游戏。 而实现本地化的方案也有很多种,各个方案之间也各有优劣,后面也会对多个方案进行介绍学习。 本文就来介绍一个专门作用于多语言本地化的Unity官方插件:Localization 。 这个插件方便进行游戏的多语言本地化,让游戏支持多种语言,下面就来看看该插件的使用方法吧!
|
4月前
|
定位技术 C# 图形学
Unity和C#游戏编程入门:创建迷宫小球游戏示例
Unity和C#游戏编程入门:创建迷宫小球游戏示例
76 2
|
9月前
|
开发框架 Java .NET
《unity游戏优化》第8章内存优化
《unity游戏优化》第8章内存优化
|
5月前
|
运维 API C#
【Unity游戏破解】外挂原理分析
【Unity游戏破解】外挂原理分析
170 0
【Unity游戏破解】外挂原理分析