Windows平台如何实现RTSP|RTMP流录像?

好多开发者使用场景,除了实现基础的低延迟RTSP、RTMP播放外,还需要实现RTSP、RTMP流数据的本地录像功能。本文以大牛直播SDK的Windows平台播放模块为例,介绍下如何实现RTSP、RTMP流录像。

功能设计

  •  [拉流]支持拉取RTSP流录像;
  •  [拉流]支持拉取RTMP流录像;
  •  [逻辑分离]和播放、转发功能完全分离,支持随时录像;
  •  [参数设置]支持设置单个录像文件大小、录像路径等,并支持纯音频、纯视频、音视频录制模式;
  •  [音频转码]支持音频(PCMU/PCMA,Speex等)转AAC后再录像;
  •  [265支持]支持RTSP/RTMP H.265录制到MP4文件;
  •  [事件回调]从开始录像,到录像结束均有event callback上来。

引入相关头文件和库

C#头文件:

  • [base code定义]nt_base_code_define.cs
  • [player接口]smart_player_define.cs
  • [player参数定义]smart_player_sdk.cs

相关Lib:

  • SmartLog.dll
  • SmartLog.lib
  • SmartPlayerSDK.dll
  • SmartPlayerSDK.lib
  • avcodec-56.dll
  • avdevice-56.dll
  • avfilter-5.dll
  • avformat-56.dll
  • avutil-54.dll
  • postproc-53.dll
  • swresample-1.dll
  • swscale-3.dll

 设置日志存放路径

需要在player_api_.Init之前添加下面的代码:

// 设置日志路径(请确保目录存在)
String log_path = "D:\\playerlog";
NTSmartLog.NT_SL_SetPath(log_path);

如目录存在,并具备文件写入权限,关闭应用程序后,相关文件夹下会有smart_sdk.log生成。

初始化SDK

NT_SP_Init:SDK初始化,多实例播放,此接口仅需调用一次即可。

 创建播放实例

NT_SP_Open:每调用一次Open接口,对应一个播放实例,如需播放多实例,对应多个player handler。

if (player_handle_ == IntPtr.Zero)
{player_handle_ = new IntPtr();UInt32 ret_open = NTSmartPlayerSDK.NT_SP_Open(out player_handle_, IntPtr.Zero, 0, IntPtr.Zero);if (ret_open != 0){player_handle_ = IntPtr.Zero;MessageBox.Show("调用NT_SP_Open失败..");return;}
}

设置回调事件

NT_SP_SetEventCallBack:用于回调网络链接状态、buffer状态(开始、buffer比例、结束)、实时带宽等,对应EventID如下:

/*事件ID*/
public enum NT_SP_E_EVENT_ID : uint
{NT_SP_E_EVENT_ID_BASE = NTBaseCodeDefine.NT_EVENT_ID_SMART_PLAYER_SDK,NT_SP_E_EVENT_ID_CONNECTING          = NT_SP_E_EVENT_ID_BASE | 0x2, /*连接中*/NT_SP_E_EVENT_ID_CONNECTION_FAILED = NT_SP_E_EVENT_ID_BASE | 0x3, /*连接失败*/NT_SP_E_EVENT_ID_CONNECTED       = NT_SP_E_EVENT_ID_BASE | 0x4, /*已连接*/NT_SP_E_EVENT_ID_DISCONNECTED     = NT_SP_E_EVENT_ID_BASE | 0x5, /*断开连接*/NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED = NT_SP_E_EVENT_ID_BASE | 0x8,  /*收不到RTMP数据*/NT_SP_E_EVENT_ID_RTSP_STATUS_CODE   = NT_SP_E_EVENT_ID_BASE | 0xB,  /*rtsp status code上报, 目前只上报401, param1表示status code*//* 接下来请从0x81开始*/NT_SP_E_EVENT_ID_START_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x81, /*开始缓冲*/NT_SP_E_EVENT_ID_BUFFERING     = NT_SP_E_EVENT_ID_BASE | 0x82, /*缓冲中, param1 表示百分比进度*/NT_SP_E_EVENT_ID_STOP_BUFFERING  = NT_SP_E_EVENT_ID_BASE | 0x83, /*停止缓冲*/NT_SP_E_EVENT_ID_DOWNLOAD_SPEED  = NT_SP_E_EVENT_ID_BASE | 0x91, /*下载速度, param1表示下载速度,单位是(Byte/s)*/NT_SP_E_EVENT_ID_PLAYBACK_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa1,     /*播放结束, 直播流没有这个事件,点播流才有*/NT_SP_E_EVENT_ID_RECORDER_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa2,     /*录像结束, 直播流没有这个事件, 点播流才有*/NT_SP_E_EVENT_ID_PULLSTREAM_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa3,   /*拉流结束, 直播流没有这个事件,点播流才有*/NT_SP_E_EVENT_ID_DURATION = NT_SP_E_EVENT_ID_BASE | 0xa8, /*视频时长,如果是直播,则不上报,如果是点播的话, 若能从视频源获取视频时长的话,则上报, param1表示视频时长,单位是毫秒(ms)*/
}

设置拉流的URL

NT_SP_SetURL:支持rtsp/rtmp/本地FLV文件(全路径)。

设置录像规则

  1. NT_SP_SetRecorderDirectory:设置录像目录
  2. NT_SP_SetRecorderFileMaxSize:设置单个文件最大大小
  3. NT_SP_SetRecorderFileNameRuler:设置录像文件名生成规则
  4. NT_SP_SetRecorderCallBack:设置录像回调接口
  5. NT_SP_SetRecorderAudioTranscodeAAC:设置录像时音频转AAC编码的开关, aac比较通用,sdk增加其他音频编码(比如speex, pcmu, pcma等)转aac的功能
  6. NT_SP_SetRecorderVideo:设置是否录视频,默认的话,如果视频源有视频就录,没有就没得录, 但有些场景下可能不想录制视频,只想录音频,所以增加个开关
  7. NT_SP_SetRecorderAudio:设置是否录音频,默认的话,如果视频源有音频就录,没有就没得录, 但有些场景下可能不想录制音频,只想录视频,所以增加个开关

实现录像逻辑

  1. NT_SP_StartRecorder:启动录像
  2. NT_SP_StopRecorder:停止录像

代码调用示例:

/** SmartPlayerForm.cs* Author: daniusdk.com* WeChat: xinsheng120*/
private void btn_record_Click(object sender, EventArgs e)
{if (player_handle_ == IntPtr.Zero)return;if (btn_record.Text == "录像"){if (!is_rec_video_ && !is_rec_audio_){MessageBox.Show("音频录制选项和视频录制选项至少需要选择一个!");return;}if (!is_playing_){if (!InitCommonSDKParam()){MessageBox.Show("设置参数错误!");return;}}NTSmartPlayerSDK.NT_SP_SetRecorderVideo(player_handle_, is_rec_video_ ? 1 : 0);NTSmartPlayerSDK.NT_SP_SetRecorderAudio(player_handle_, is_rec_audio_ ? 1 : 0);UInt32 ret = NTSmartPlayerSDK.NT_SP_SetRecorderDirectoryW(player_handle_, rec_dir_);if (NT.NTBaseCodeDefine.NT_ERC_OK != ret){MessageBox.Show("设置录像目录失败");return;}NTSmartPlayerSDK.NT_SP_SetRecorderFileMaxSize(player_handle_, max_file_size_);NT_SP_RecorderFileNameRuler rec_name_ruler = new NT_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(player_handle_, ref rec_name_ruler);record_call_back_ = new SP_SDKRecorderCallBack(SDKRecorderCallBack);NTSmartPlayerSDK.NT_SP_SetRecorderCallBack(player_handle_, IntPtr.Zero, record_call_back_);NTSmartPlayerSDK.NT_SP_SetRecorderAudioTranscodeAAC(player_handle_, is_audio_transcode_aac_ ? 1 : 0);if (NT.NTBaseCodeDefine.NT_ERC_OK != NTSmartPlayerSDK.NT_SP_StartRecorder(player_handle_)){MessageBox.Show("录像失败!");return;}btn_record.Text = "停止录像";is_recording_ = true;}else{StopRecorder();}
}

录像事件回调

/** 录像回调* status: 1:表示开始写一个新录像文件. 2:表示已经写好一个录像文件* file_name: 实际录像文件名*/
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]public delegate void SP_SDKRecorderCallBack(IntPtr handle, IntPtr user_data, UInt32 status, [MarshalAs(UnmanagedType.LPStr)] String file_name);

调用示例:

private void RecordCallBack(UInt32 status, [MarshalAs(UnmanagedType.LPStr)] String file_name)
{byte[] utf8_bytes = Encoding.Default.GetBytes(file_name);byte[] default_bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, utf8_bytes);String recorder_file_name = Encoding.Default.GetString(default_bytes);StringBuilder sb = new StringBuilder();sb.Append("录像状态:");if (status == 1){sb.Append("new file: ");}else if(status == 2){sb.Append("finished file: ");}sb.Append(recorder_file_name);MessageBox.Show(sb.ToString());
}

销毁播放实例

NT_SP_Close

调用Close接口后,player handler置空。

if ( player_handle_ != IntPtr.Zero)
{NTSmartPlayerSDK.NT_SP_Close(player_handle_);player_handle_ = IntPtr.Zero;
}

释放资源

NT_SP_UnInit

UnInit() 是SDK最后一个调用的接口,多实例环境下,只需要调用一次即可。

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

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

相关文章

15分钟学 Python 第34天 :小项目-个人博客网站

Day 34: 小项目-个人博客网站 1. 引言 随着互联网的普及,个人博客已成为分享知识、体验和见解的一个重要平台。在这一节中,我们将使用Python的Flask框架构建一个简单的个人博客网站。我们将通过实际的项目来学习如何搭建Web应用、处理用户输入以及管理…

二叉树深度学习——将二叉搜索树转化为排序的双向链表

1.题目解析 题目来源:LCR 155.将二叉搜索树转化为排序的双向链表 测试用例 2.算法原理 首先题目要求原地进行修改并且要求左指针代表前驱指针,右指针代表后继指针,所以思路就是 1.使用前序遍历创建两个指针cur、prev代表当前节点与前一个节点…

游览器输入URL并Enter时都发生了什么 面试完美回答

文章目录 前言URL解析DNS解析**浏览器缓存****操作系统缓存**:**路由器缓存**:ISP(Internet service provider)缓存DNS递归解析IP地址的获取缓存结果 建立TCP连接发送HTTP请求服务器响应TCP链接断开渲染页面解析一 HTML解析过程解…

U盘目录损坏数据恢复全攻略

一、U盘目录损坏现象描述 U盘作为我们日常生活中常用的存储设备,因其小巧便携、存储容量大等特点而备受青睐。然而,在使用U盘的过程中,有时会遇到目录损坏的问题。目录损坏通常表现为U盘中的文件夹无法正常打开,或者文件无法读取…

云栖实录 | 开源大数据全面升级:Native 核心引擎、Serverless 化、湖仓架构引领云上大数据发展

本文根据2024云栖大会实录整理而成,演讲信息如下: 演讲人: 王 峰 | 阿里云智能集团研究员、开源大数据平台负责人 李 钰|阿里云智能集团资深技术专家 范 振|阿里云智能集团高级技术专家 李劲松|阿里云…

docker部署minio文件服务器

1. 拉取镜像 docker search minio docker pull minio/minio2. 创建映射 mkdir -p /root/docker_app/minio_data mkdir -p /root/docker_app/minio_config3. 执行docker run 自定义用户和秘钥安装: admin/admin123456 docker run -p 9000:9000 -p 9001:9001 -d --name mini…

【有啥问啥】大型语言模型的涌现能力(Emergent Abilities):新一代AI的曙光

大型语言模型的涌现能力(Emergent Abilities):新一代AI的曙光 随着人工智能技术的飞速发展,大型语言模型(Large Language Model,LLM)展现出了令人惊叹的涌现能力。这种能力并非模型规模简单线性…

Unity3D播放GIF图片使用Animation来制作动画

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、下载GIF动图,用PS制作导出帧动画图片👉二、使用Animation制作动画👉三、脚本控制动画播放👉壁纸分享👉总结👉前言 unity播放gif图片,本身是不支持的,但是可以使用其他方法来实现, 1.有一种使用System…

tortorise数据库迁移变化aerich

数据库迁移 使用场景,当需要修改定义的数据库中表的数据时,就可以利用aerich进行迁移改动 例如 class Asset(models.Model):aid fields.CharField(max_length50, pkTrue)asset_name fields.CharField(max_length150)target_name fields.CharField(…

AI 搜索引擎工具集合

🐣个人主页 可惜已不在 🐤这篇在这个专栏AI_可惜已不在的博客-CSDN博客 🐥有用的话就留下一个三连吧😼 目录 前言 AI 搜索引擎 前言 在信息爆炸的时代,A 搜索引擎应运而生。它以强大的人工智能技术为支撑&#xff0…

day2网络编程项目的框架

基于终端的 UDP云聊天系统 开发环境 Linux 系统GCCUDPmakefilesqlite3 功能描述 通过 UDP 网络使服务器与客户端进行通信吗,从而实现云聊天。 Sqlite数据库 用户在加入聊天室前,需要先进行用户登录或注册操作,并将注册的用户信息&#xf…

windows配置C++编译环境和VScode C++配置(保姆级教程)

1.安装MinGW-w64 MinGW-w64是一个开源的编译器套件,适用于Windows平台,支持32位和64位应用程序的开发。它包含了GCC编译器、GDB调试器以及其他必要的工具,是C开发者在Windows环境下进行开发的重要工具。 我找到了一个下载比较快的链接&#…

第四届机器人、自动化与智能控制国际会议(ICRAIC 2024)征稿

第四届机器人、自动化与智能控制国际会议(ICRAIC 2024)由湖南第一师范学院主办,南京师范大学、山东女子学院、爱迩思出版社(ELSP)协办。 大会将专注于机器人、数字化、自动化、人工智能等技术的开发和融合&#xff0c…

HarmonyOS鸿蒙系统开发应用程序,免费开源DevEco Studio开发工具

DevEco Studio 是华为为 HarmonyOS 和 OpenHarmony 开发者提供的官方集成开发环境(IDE),它基于 IntelliJ IDEA Community 版本打造,提供了代码编辑、编译、调试、发布等一体化服务。 一、DevEco Studio支持系统 DevEco Studio支持…

更美观的HTTP性能监测工具:httpstat

reorx/httpstat是一个旨在提供更美观和详细HTTP请求统计信息的cURL命令行工具,它能够帮助开发者和运维人员深入理解HTTP请求的性能和状态。 1. 基本概述 项目地址:https://github.com/reorx/httpstat语言:该工具主要是以Python编写&#xff…

C++之多线程

前言 多线程和多进程是并发编程的两个核心概念,它们在现代计算中都非常重要,尤其是在需要处理大量数据、提高程序性能和响应能力的场景中。 多线程的重要性: 资源利用率:多线程可以在单个进程中同时执行多个任务,这可以更有效地利用CPU资源,特别是在多核处理器上。 性…

SpringSession微服务

一.在linux中确保启动起来redis和nacos 依赖记得别放<dependencyManagement></dependencyManagement>这个标签去了 1.首先查看已经启动的服务 docker ps 查看有没有安装redis和nacos 2.启动redis和nacos 发现没有启动redis和nacos,我们先来启动它。&#xff0c;…

BiLSTM模型实现电力数据预测

基础模型见&#xff1a;A020-LSTM模型实现电力数据预测 1. 引言 时间序列预测在电力系统管理、负荷预测和能源优化等领域具有重要意义。传统的单向长短期记忆网络&#xff08;LSTM&#xff09;因其在处理时间序列数据中的优势&#xff0c;广泛应用于此类任务。然而&#xff0…

会议平台后端优化方案

会议平台后端优化方案 通过RTC的学习&#xff0c;我了解到了端对端技术&#xff0c;就想着做一个节省服务器资源的会议平台 之前做了这个项目&#xff0c;快手二面被问到卡着不知如何介绍&#xff0c;便有了这篇文章 分析当下机制 相对于传统视频平台&#xff08;SFU&#xff…

Pikachu-Cross-Site Scripting-DOM型xss

DOM型xss DOM型XSS漏洞是一种特殊类型的XSS,是基于文档对象模型 Document Object Model (DOM)的一种漏洞。是一个与平台、编程语言无关的接口&#xff0c;它允许程序或脚本动态地访问和更新文档内容、结构和样式&#xff0c;处理后的结果能够成为显示页面的一部分。 dom就是一…