Windows平台RTMP推送|轻量级RTSP服务录像模块如何支持中文路径?

技术背景

我们在做Windows平台RTMP推送、轻量级RTSP服务录像模块的时候,部分开发者抱怨路径无法设置中文,只能设置为英文。

以C#的接口为例,早期的设计如下:

   /** 设置本地录像目录, 必须是英文目录,否则会失败*/[DllImport(@"SmartPublisherSDK.dll")]public static extern UInt32 NT_PB_SetRecorderDirectory(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] String dir, IntPtr pReserve);

考虑到一些场景的特殊性,可能需要中文路径,我们设计的接口如下:

        /** 设置本地录像目录, 支持中文目录, 需要设置宽字符,比如L"D:\\xxx\\gg"*/[DllImport(@"SmartPublisherSDK.dll")]public static extern UInt32 NT_PB_SetRecorderDirectoryW(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)]String dir, IntPtr pReserve);

调用如下,以调用开始录像、暂停录像、停止录像为例,调用逻辑如下,可以看到除了中文路径诉求,录像模块还可以添加前缀、添加文字、水印:

       public bool StartRecorder(){if (is_empty_handle() || is_recording())return false;//string edit_rec_dir = "D:\\dntest";string edit_rec_dir = "D:\\推送端录像";if (String.IsNullOrEmpty(edit_rec_dir)){Console.WriteLine("请设置录像目录");return false;}uint ret = NTSmartPublisherSDK.NT_PB_SetRecorderDirectoryW(handle_, edit_rec_dir, IntPtr.Zero);if (NTBaseCodeDefine.NT_ERC_OK != ret){try_close_handle();return false;}uint rec_max_file_size = 512 * 1024;NTSmartPublisherSDK.NT_PB_SetRecorderFileMaxSize(handle_, rec_max_file_size);NT_PB_RecorderFileNameRuler rec_name_ruler = new NT_PB_RecorderFileNameRuler();String rec_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_, ref rec_name_ruler);if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPublisherSDK.NT_PB_StartRecorder(handle_, IntPtr.Zero)){try_close_handle();return false;}shared_lock_.EnterWriteLock();try{handle_reference_count_++;is_recording_ = true;}finally{shared_lock_.ExitWriteLock();}return true;}public UInt32 PauseRecorder(bool is_pause){if (is_empty_handle() || !is_recording())return NTBaseCodeDefine.NT_ERC_FAILED;UInt32 ret = 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("暂停录像失败, 请重新尝试!");return ret;}else if (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("恢复录像失败, 请重新尝试!");return ret;}else if (NTBaseCodeDefine.NT_ERC_OK == ret){//btn_pause_rec.Text = "暂停录像";}}return ret;}public void StopRecorder(){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();}

开始录像和录像完成后,提示如下:

        private void PbEventCallBack(UInt32 event_id,Int64 param1,Int64 param2,UInt64 param3,UInt64 param4,[MarshalAs(UnmanagedType.LPStr)] String param5,[MarshalAs(UnmanagedType.LPStr)] String param6,IntPtr param7){String event_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);String file_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);String finished_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服务配套的录像模块,除了设置录像保存路径外、还可以设置录像文件前缀、是不是添加日期、时间等,还有就是单个录像文件大小,超过这个大小后,会自动切换到下个文件,需要测试交流的,可以跟我联系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/620549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java SE语法篇】8.面向对象三大特征——封装、继承和多态

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 文章目录 1. 封装1.1 封装的概念1.2 为什么封装1.3 封装的实现…

Leetcode with Golang 滑动窗口 Part1

滑动窗口的定义: 滑动窗口这一个技巧主要运用于处理数组问题上,一般用于“子串”问题。精髓是,维护一个里面装着元素的“窗口”,在将新元素装进“窗口”的同时,根据题意,把不符合题意的元素踢出“窗口”。…

漏洞复现-nginxWebUI runCmd前台远程命令执行漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

1222. 密码脱落(dp划分)

题目&#xff1a; 1222. 密码脱落 - AcWing题库 思路&#xff1a; 代码&#xff1a; #include<cstdio> #include<cstring> using namespace std; const int N1010; int f[N][N];//表示以L和R为两端点的字符串的“最长”回文序列长度 char s[N];//存储输入的字符串…

buuctf-Misc 题目解答分解115-117

115.派大星的烦恼 解压下载文件时一个 bmp 文件&#xff0c;用notepad 打开有没有发现什么 &#xff0c;提示位图什么的 用Stegsolve.jar 打开 发现很多. 和- 第一时间想到了 电报码 但提示不是电报码&#xff0c;除了这个那就是很像二进制了 0,1 什么的&#xff0c;但这个感觉…

Sqoop与其他数据采集工具的比较分析

比较Sqoop与其他数据采集工具是一个重要的话题&#xff0c;因为不同的工具在不同的情况下可能更适合。在本博客文章中&#xff0c;将深入比较Sqoop与其他数据采集工具&#xff0c;提供详细的示例代码和全面的内容&#xff0c;以帮助大家更好地了解它们之间的差异和优劣势。 Sq…

六、新建窗体时,几种窗体的区别

新建窗体时&#xff0c;会有几种类型的选项&#xff0c;很多同学不明白其中的意思&#xff0c;我们在本章节中详细介绍一下几种窗体的区别。 窗体的类型分以下几种 Dialog with Buttons Bottom 带按钮的对话框&#xff0c;按钮在底部 Dialog with Buttons Right 带按钮的对话框…

【计算机组成原理】高速缓冲存储器 Cache 的写策略(Writing Policy)

写策略 Writing Policy 缓存的写策略指的是确定何时将数据写入缓存或主存的策略。 写命中 Write Hit 全写法 Write Through 在全写法策略中&#xff0c;每次发生写操作时都会将数据同时写入缓存和主存。这样可以保证数据的一致性&#xff0c;但会增加主存的写入操作&#xf…

深入 Move 生态,探秘铭文热潮背后的思考

Move 语言是 Meta&#xff08;Facebook&#xff09;在 2018 年开发的新一代智能合约编程语言。回顾过去的一年&#xff0c;Aptos 与 Sui 主网上线&#xff0c;为整个 Web3 开启了下一个十亿用户服务的新征程。Rooch、Initia、MoveMent 等多条使用 Move 语言的区块链网络涌现&am…

1 pytest入门

pytest入门 示例成功失败 1.1 资源获取官方文档安装 1.2 运行 Pytest测试搜索命名规则 1.3 运行单个测试用例1.4 使用命令行选项-h&#xff08;--help&#xff09;--collect-only-k-m-x--maxfailnum-s 与 --capturemethod-s 等价于 --captureno--capturesys--capturefd -l&…

win10重新安装Windows应用商店

安装Windows 终端 用 PowerShell 重装 Microsoft Store使用 MSIX 包重装 Microsoft Store下载安装包及依赖下载Windows 应用商店的安装包安装包是依赖组件包 微软应用商店无法连接网络解决办法 参考&#xff1a; wind10自带的终端程序和powerShell 真是太垃圾了&#xff0c; 突…

CF1178F1 Short Colorful Strip 题解

Short Colorful Strip 传送门 题面翻译 题目描述 这是F题的第一个子任务。F1和F2的区别仅在对于m和时间的限制上 有n1种颜色标号从0到n&#xff0c;我们有一条全部染成颜色0的长为m的纸带。 Alice拿着刷子通过以下的过程来给纸带染色&#xff1a; 我们按照从1到n的顺序进…

C++标准学习--decltype

decltype / auto 是具有类型推导功能的 类型 描述/占位 符 decltype: 获取对象或表达式的类型auto: 类型自动推导 decltype 可以获取变量类型&#xff0c; &#xff08;并不同于python的type&#xff0c;但python能打印出type获取的名称&#xff0c; C通过typeid实现&#xff…

Vue基知识四

本文对前边几章所学习的内容&#xff0c;以案例的形式做一个总结 一 TodoList案例 即待办事项案例&#xff0c;效果如下 1.1 组件化编码流程&#xff08;通用&#xff09; 这是编码时的通用流程&#xff0c;以后也可以按照这个流程来写代码&#xff08;熟悉后这个流程的顺…

定时器问题(vue的问题)

我在a页面写一个定时&#xff0c;让他每秒钟打印一个1&#xff0c;然后跳转到b页面&#xff0c;此时可以看到&#xff0c;定时器依然在执行。这样是非常消耗性能的。如下图所示&#xff1a; 解决方法1 首先我在data函数里面进行定义定时器名称&#xff1a; data() {return {t…

SpringBoot 引入分页插件 PageHelper

官网 https://pagehelper.github.io/docs/howtouse/ 引入步骤 第1步&#xff1a;引入依赖 <!--分页插件--> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.2</ver…

Open3D 计算点云质心和中心(18)

Open3D 计算点云质心和中心(18) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 质心和中心是有所区别的,点云质心可以看作每个点的坐标均值,点云中心可以看作点云所在包围盒的中心,这也是上一章坐标最值的常用方法,下面就两种方法进行实现(图例,大概就是这个意思…

Android WiFi Service启动-Android13

Android WiFi Service启动 - Android13 1、SystemServer中入口2、WifiService启动2.1 关键类概要2.2 启动时序图 Android WiFi基础概览 AOSP > 文档 > 心主题 > WiFi概览 1、SystemServer中入口 编译生成对应的jar包&#xff1a;"/apex/com.android.wifi/javalib…

高性能RPC框架解密

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

编译和链接(2)

3. 预处理详解 3.2#define 3.2.5带副作用的宏参数 当宏参数在宏的定义中出现超过一次的时候&#xff0c;如果参数带有副作用&#xff0c;那么你在使用这个宏的时候就可能 出现危险&#xff0c;导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。 例如&…