技术背景
我们在做Windows平台RTMP推送、轻量级RTSP服务录像模块的时候,部分开发者抱怨路径无法设置中文,只能设置为英文。
编辑
以C#的接口为例,早期的设计如下:
/** 设置本地录像目录, 必须是英文目录,否则会失败*/ [DllImport(@"SmartPublisherSDK.dll")] publicstaticexternUInt32NT_PB_SetRecorderDirectory(IntPtrhandle, [MarshalAs(UnmanagedType.LPStr)] Stringdir, IntPtrpReserve);
考虑到一些场景的特殊性,可能需要中文路径,我们设计的接口如下:
/** 设置本地录像目录, 支持中文目录, 需要设置宽字符,比如L"D:\\xxx\\gg"*/ [DllImport(@"SmartPublisherSDK.dll")] publicstaticexternUInt32NT_PB_SetRecorderDirectoryW(IntPtrhandle, [MarshalAs(UnmanagedType.LPWStr)]Stringdir, IntPtrpReserve);
调用如下,以调用开始录像、暂停录像、停止录像为例,调用逻辑如下,可以看到除了中文路径诉求,录像模块还可以添加前缀、添加文字、水印:
publicboolStartRecorder() { if (is_empty_handle() ||is_recording()) returnfalse; //string edit_rec_dir = "D:\\dntest";stringedit_rec_dir="D:\\推送端录像"; if (String.IsNullOrEmpty(edit_rec_dir)) { Console.WriteLine("请设置录像目录"); returnfalse; } uintret=NTSmartPublisherSDK.NT_PB_SetRecorderDirectoryW(handle_, edit_rec_dir, IntPtr.Zero); if (NTBaseCodeDefine.NT_ERC_OK!=ret) { try_close_handle(); returnfalse; } uintrec_max_file_size=512*1024; NTSmartPublisherSDK.NT_PB_SetRecorderFileMaxSize(handle_, rec_max_file_size); NT_PB_RecorderFileNameRulerrec_name_ruler=newNT_PB_RecorderFileNameRuler(); Stringrec_file_name_prefix_="transcode-rec"; rec_name_ruler.file_name_prefix_=rec_file_name_prefix_.ToString(); rec_name_ruler.append_date_=1; rec_name_ruler.append_time_=1; NTSmartPublisherSDK.NT_PB_SetRecorderFileNameRuler(handle_, refrec_name_ruler); if (NTBaseCodeDefine.NT_ERC_OK!=NTSmartPublisherSDK.NT_PB_StartRecorder(handle_, IntPtr.Zero)) { try_close_handle(); returnfalse; } shared_lock_.EnterWriteLock(); try { handle_reference_count_++; is_recording_=true; } finally { shared_lock_.ExitWriteLock(); } returntrue; } publicUInt32PauseRecorder(boolis_pause) { if (is_empty_handle() ||!is_recording()) returnNTBaseCodeDefine.NT_ERC_FAILED; UInt32ret=NTBaseCodeDefine.NT_ERC_OK; if (is_pause) { ret=NTSmartPublisherSDK.NT_PB_PauseRecorder(handle_, 1); if ((UInt32)NT.NTSmartPublisherDefine.NT_PB_E_ERROR_CODE.NT_ERC_PB_NEED_RETRY==ret) { Console.WriteLine("暂停录像失败, 请重新尝试!"); returnret; } elseif (NTBaseCodeDefine.NT_ERC_OK==ret) { //btn_pause_rec.Text = "恢复录像"; } } else { ret=NTSmartPublisherSDK.NT_PB_PauseRecorder(handle_, 0); if ((UInt32)NT.NTSmartPublisherDefine.NT_PB_E_ERROR_CODE.NT_ERC_PB_NEED_RETRY==ret) { Console.WriteLine("恢复录像失败, 请重新尝试!"); returnret; } elseif (NTBaseCodeDefine.NT_ERC_OK==ret) { //btn_pause_rec.Text = "暂停录像"; } } returnret; } publicvoidStopRecorder() { if (is_empty_handle() ||!is_recording()) return; shared_lock_.EnterWriteLock(); try { is_recording_=false; handle_reference_count_--; } finally { shared_lock_.ExitWriteLock(); } NTSmartPublisherSDK.NT_PB_StopRecorder(handle_); try_close_handle(); }
开始录像和录像完成后,提示如下:
privatevoidPbEventCallBack(UInt32event_id, Int64param1, Int64param2, UInt64param3, UInt64param4, [MarshalAs(UnmanagedType.LPStr)] Stringparam5, [MarshalAs(UnmanagedType.LPStr)] Stringparam6, IntPtrparam7) { Stringevent_log=""; switch (event_id) { ...... case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_RECORDER_START_NEW_FILE: event_log=" start new recorder file"; byte[] utf8_bytes=Encoding.Default.GetBytes(param5); byte[] default_bytes=Encoding.Convert(Encoding.UTF8, Encoding.Default, utf8_bytes); Stringfile_name=Encoding.Default.GetString(default_bytes); if (!String.IsNullOrEmpty(file_name)) { event_log=event_log+" file name:"+file_name; } break; case (uint)NTSmartPublisherDefine.NT_PB_E_EVENT_ID.NT_PB_E_EVENT_ID_ONE_RECORDER_FILE_FINISHED: event_log=" finish recorder file"; byte[] finished_utf8_bytes=Encoding.Default.GetBytes(param5); byte[] finished_default_bytes=Encoding.Convert(Encoding.UTF8, Encoding.Default, finished_utf8_bytes); Stringfinished_file_name=Encoding.Default.GetString(finished_default_bytes); if (!String.IsNullOrEmpty(finished_file_name)) { event_log=event_log+" file name:"+finished_file_name; } break; ....... default: break; } EventGetPublisherEventMsg(event_log); }
总结
Windows平台RTMP推送、轻量级RTSP服务配套的录像模块,除了设置录像保存路径外、还可以设置录像文件前缀、是不是添加日期、时间等,还有就是单个录像文件大小,超过这个大小后,会自动切换到下个文件,需要测试交流的,可以跟我联系。