很多开发者提到,拉取的摄像机(一般RTSP流)或RTMP流,如果需要录制,需要考虑哪些因素,本文以大牛直播SDK的Windows平台拉流端录像为例(github),做个简单的介绍:
1. 基础文件名设定
一般来说,本地录像的话,不可能每个文件单独命名,这个时候,需要考虑如文件名前缀、文件名是否添加日期、是否添加时间几个因素,以C#为例,具体接口定义如下:
/*如果三项都是0的话,将不能启动录像*/ [StructLayoutAttribute(LayoutKind.Sequential)] public struct NT_SP_RecorderFileNameRuler { public UInt32 type_; // 这个值目前默认是0,将来扩展用 [MarshalAs(UnmanagedType.LPStr)] public String file_name_prefix_; // 设置一个录像文件名前缀, 例如:daniulive public Int32 append_date_; // 如果是1的话,将在文件名上加日期, 例如:daniulive-2017-01-17 public Int32 append_time_; // 如果是1的话,将增加时间,例如:daniulive-2017-01-17-17-10-36 } /* * 设置录像文件名生成规则 */ [DllImport(@"SmartPlayerSDK.dll", EntryPoint = "NT_SP_SetRecorderFileNameRuler", CallingConvention = CallingConvention.StdCall)] public static extern UInt32 NT_SP_SetRecorderFileNameRuler(IntPtr handle, ref NT_SP_RecorderFileNameRuler ruler);
2. 设置录像目录、单个录像文件大小
这个不再赘述,设置录像目录是录像的基础操作,单个文件大小设定,可以更精细的控制单个文件size,一般建议单个文件不要过大,单次录制,超过设定的size,将自动切分保存到另外一个新的文件。
/* * 设置本地录像目录, 必须是英文目录,否则会失败 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_SetRecorderDirectory(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] String dir); /* * 设置单个录像文件最大大小, 当超过这个值的时候,将切割成第二个文件 * size: 单位是KB(1024Byte), 当前范围是 [5MB-800MB], 超出将被设置到范围内 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_SetRecorderFileMaxSize(IntPtr handle, UInt32 size);
3. 音频转码后录像
一般来说,AAC格式更通用,设置录像时音频转AAC编码的开关, 可以把比如speex, pcmu, pcma转aac的后再录像,确保录制文件的audio格式更通用,转码会有一定的资源消耗。
/* * 设置录像时音频转AAC编码的开关, aac比较通用,sdk增加其他音频编码(比如speex, pcmu, pcma等)转aac的功能. * is_transcode: 设置为1的话,如果音频编码不是aac,则转成aac, 如果是aac,则不做转换. 设置为0的话,则不做任何转换. 默认是0. * 注意: 转码会增加性能消耗 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_SetRecorderAudioTranscodeAAC(IntPtr handle, Int32 is_transcode);
4. 更精细的音视频录像控制(纯音频、纯视频录制)
这两组接口设置的意义在于, 有些场景下可能不想录制视频,只想录音频,或是只录制视频、不录制音频,通过开放此类接口设定,让开发者操作更灵活。
/* * 设置是否录视频,默认的话,如果视频源有视频就录,没有就没得录, 但有些场景下可能不想录制视频,只想录音频,所以增加个开关 * * is_record_video: 1 表示录制视频, 0 表示不录制视频, 默认是1 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_SetRecorderVideo(IntPtr handle, Int32 is_record_video); /* * 设置是否录音频,默认的话,如果视频源有音频就录,没有就没得录, 但有些场景下可能不想录制音频,只想录视频,所以增加个开关 * * is_record_audio: 1 表示录制音频, 0 表示不录制音频, 默认是1 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_SetRecorderAudio(IntPtr handle, Int32 is_record_audio);
5. 容易被忽略的callback事件
第五条,录像状态反馈,是好多开发者容易遗忘的,录像回调状态,可以很方便的告知上层开发者,什么时候开启了录像,什么时候结束了录像,什么时候写入了新的录像文件,这样便于上层逻辑开发人员,对录制好的文件进行二次编辑或处理。
/* * 设置录像回调接口 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_SetRecorderCallBack(IntPtr handle, IntPtr call_back_data, SP_SDKRecorderCallBack call_back);
6. 开始录像/停止录像
不再赘述,有了以上5条的设计,第六条,只要上层开发者按部就班的调用就好了。
/* * 启动录像 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_StartRecorder(IntPtr handle); /* * 停止录像 */ [DllImport(@"SmartPlayerSDK.dll")] public static extern UInt32 NT_SP_StopRecorder(IntPtr handle);
总结:
以上是一个友好的RTSP、RTMP拉流录像功能需要考虑的几点设计,遗憾的是,好多开发者之关注第六条,前五条或多或少的忽略了,除了常规的接口设计之外,录像功能需要考虑的其他因素还很多,后续有机会再做进一步分享。