C# 实现腾讯云多路直播流的云端混合录制

news2024/10/5 9:11:40

目录

 应用场景

腾讯云直播和云点播

产品架构

混流显示示例 

关键代码

API实现

小结


 应用场景

在云考试或视频面试中,除了对考生、考官的实时音视频监控以防止作弊行为的发生以外,对直播流的音视频录制也尤为重要,可做为后期证据材料进行追溯、举证。

在实际的应用场景中,会有多路直播流的产生,因此根据业务需要可以将多路直播流混合录制成一个视频文件,腾讯云称其为云端混录。混录后的视频可以更加直观的进行回放,可以同时查看多路直播流的视频情况。

混录场景举例:

场景1:在线考试回放,三路混流。主图像显示考生面部及背后方视频、副图1显示考生正前方视频、副图2显示屏幕共享视频。

场景2:一对一视频面试,两路混流。主图显示考生答题情况视频、副图1显示考官提问情况视频。

腾讯云直播和云点播

云端混流涉及腾讯云直播和云点播服务。

腾讯云直播(Cloud Streaming Services,CSS)提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,提供标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,提供一站式的音视频直播解决方案。具体可访问该网址进行了解:https://cloud.tencent.com/product/css

腾讯云点播(VOD)面向音视频、图片等媒体,提供制作上传、存储、转码、媒体处理、媒体 AI、加速分发播放、版权保护等一体化的高品质媒体服务。具体可访问该网址进行了解:https://cloud.tencent.com/product/vod

产品架构

下图是我们基于腾讯云产品架构图的部分采用和实现方案:

​ 

混流显示示例 

我们的混流设计输出如下图演示:

副图1显示在右上方,如果有副图2则依次向下排列。

​关于更多布局设计和产品文档请参考腾讯云产品网址进行了解:https://www.tencentcloud.com/zh/document/product/267/37665

关键代码

API实现

//混录方法,参数 mixtype,默认为混录,填写cancel为申请取消,roomid为直播房间号,userid1 为主图直播流名称,userid2 为副图直播流名称,videosize为视频分辨率,如“720p"           
 public string MixRecord(string mixtype,string roomid,string userid1,string userid2,string videosize)
            {
                roomid = int.Parse(roomid).ToString();  //对roomid进行一次转int的特殊处理
//计算主图尺寸
                int vw = 640;
                int vh = 480;
                switch (videosize)
                {
                    case "240p":
                        vw=320;vh=240;break;
                    case "360p":
                        vw=640;vh=360;break;
                    case "480p":
                        vw=640;vh=480;break;
                    case "720p":
                        vw=1280;vh=720;break;
                    case "1080p":
                        vw=1920;vh=1080;break;
                    case "1440p":
                        vw=2560;vh=1440;break;
                    case "4K":
                        vw=3840;vh=2160;break;
 
                }
//计算副图尺寸
                int svw = vw / 4;
                int svh = vh / 4;
                switch (videosize)
                {
                    case "240p":
                        svh=60; break;
                    case "360p":
                        svh=90; break;
                    case "480p":
                        svh=120; break;
                    case "720p":
                        svh=180; break;
                    case "1080p":
                        svh=270; break;
                    case "1440p":
                        svh=360; break;
                    case "4K":
                        svh = 540; break;

                }
//提供在腾讯云申请的开发帐号及开发KEY等
                string _appid = "";   
                string _sdkappid = "";
                string _key = "";
//调用腾讯云混流API
                string _interface = "Mix_StreamV2";
                MD5 md5 = new MD5();
                string _t=getTimestamp(60); //加偏移量60秒
                string _sign = md5.GetMD5Hash(_key+_t).ToLower(); //计算MD5
                
                var url = string.Format("http://fcgi.video.qcloud.com/common_access?appid={0}&interface={1}&t={2}&sign={3}",_appid,_interface,_t,_sign);

                string _timestamp = getTimestamp(0);
                string _eventid = getTimestamp(0);
                string _app_id = _appid;
                string mix_stream_session_id = roomid;
                string output_stream_id = _sdkappid + "_" + roomid + "_" + userid1 + "_main";
                string input_stream_id1 = _sdkappid + "_" + roomid + "_" + userid1 + "_main";
                string input_stream_id2 = _sdkappid + "_" + roomid + "_" + userid2 + "_main";

                var postData = "{\"timestamp\":" + _timestamp + ",\"eventId\":" + _eventid + ",\"interface\":{\"interfaceName\":\"Mix_StreamV2\",\"para\":{\"app_id\":\"" + _app_id + "\",\"interface\": \"mix_streamv2.start_mix_stream_advanced\",\"mix_stream_session_id\" : \"" + mix_stream_session_id + "\",\"output_stream_id\": \"" + output_stream_id + "\",\"input_stream_list\":[{\"input_stream_id\":\"" + input_stream_id1 + "\",\"layout_params\":{\"image_layer\":1}},{\"input_stream_id\":\"" + input_stream_id2 + "\",\"layout_params\":{\"image_layer\": 2,\"image_width\": "+svw+",\"image_height\": "+svh+",\"location_x\": "+(vw-svw-20).ToString()+",\"location_y\": 20}}]}}}";
 
                if (mixtype == "cancel")
                {
                    postData = "{\"timestamp\":"+_timestamp+",\"eventId\":"+_eventid+",\"interface\":{\"interfaceName\":\"Mix_StreamV2\",\"para\":{\"app_id\":\""+_app_id+"\",\"interface\": \"mix_streamv2.cancel_mix_stream\",\"mix_stream_session_id\" : \""+mix_stream_session_id+"\",\"output_stream_id\": \""+output_stream_id+"\"}}}";
                }
                System.Net.HttpWebRequest request;
                request = (System.Net.HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "application/json;charset=UTF-8";
                byte[] payload;
                payload = System.Text.Encoding.UTF8.GetBytes(postData);
                request.ContentLength = payload.Length;
                try
                {
                    Stream writer = request.GetRequestStream();
                    writer.Write(payload, 0, payload.Length);
                    writer.Close();
                    System.Net.HttpWebResponse response;
                    response = (System.Net.HttpWebResponse)request.GetResponse();
                    System.IO.Stream stream;
                    stream = response.GetResponseStream();
                    List<byte> bytes = new List<byte>();
                    int temp = stream.ReadByte();
                    while (temp != -1)
                    {
                        bytes.Add((byte)temp);
                        temp = stream.ReadByte();
                    }
                    byte[] result = bytes.ToArray();
                    
                    return System.Text.Encoding.Default.GetString(result);
                }
                catch (Exception ee)
                {
                    return  "{\"errcode\":2,\"errmsg\":\"" + ee.Message + "\"}";

                }
            }//request mix

            public class MD5
            {
                public  string GetMD5Hash(string str)
                {
                    //就是比string往后一直加要好的优化容器
                    StringBuilder sb = new StringBuilder();
                    using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
                    {
                        //将输入字符串转换为字节数组并计算哈希。
                        byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));

                        //X为     十六进制 X都是大写 x都为小写
                        //2为 每次都是两位数
                        //假设有两个数10和26,正常情况十六进制显示0xA、0x1A,这样看起来不整齐,为了好看,可以指定"X2",这样显示出来就是:0x0A、0x1A。 
                        //遍历哈希数据的每个字节
                        //并将每个字符串格式化为十六进制字符串。
                        int length = data.Length;
                        for (int i = 0; i < length; i++)
                            sb.Append(data[i].ToString("X2"));

                    }
                    return sb.ToString();
                }
            }

            public string getTimestamp(int seconds)
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds+seconds).ToString();
            }

小结

以上提供的代码仅供参考,在实际的应用中,我们要编写符合自己业务的逻辑,比如多路混流,还要考虑实际的运营成本,比如录制费用、存储费用等。有关腾讯云点播产品的价格情况,可以访问:https://cloud.tencent.com/act/pro/vod

云端混录在直播时进行合成,腾讯的建议是延迟一段时间再进行API申请,我在这里设置为5秒以后再申请。

为防止混录失败,我们可以在腾讯云直播管理后台,设置自动生成各路直播流的录制,以做为素材备用(会产生存储费用和录制费用),后期可以下载视频进行再合成。

以上就是自己的一些分享,时间仓促,不妥之处还请大家批评指正!

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

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

相关文章

MFA多因子认证

什么是多因子认证&#xff08;MFA&#xff09;&#xff1f;为什么需要MFA&#xff1f; 同义词 多因子认证或者多因素验证 [尤其是需要做等级保护测评的时候需要用到] 摘要 多因子认证MFA&#xff08;Multi Factor Authentication&#xff09;是一种安全认证过程&#xff0c;需…

【配置环境】VS Code怎么使用JavaScript的Mocha测试框架和Chai断言库

一&#xff0c;环境 Windows 11 家庭中文版&#xff0c;64 位操作系统, 基于 x64 的处理器VS Code 版本: 1.83.1 (user setup)Node.js 版本&#xff1a;20.9.0 二&#xff0c;安装背景 在运行测试用例时遇到 ReferenceError: describe is not defined 错误&#xff0c;网上搜寻…

信息系统项目管理师 第四版 第2章 信息技术发展

1.信息技术及其发展 1.1.计算机软硬件 程序是计算任务的处理对象和处理规则的描述、文档是为了便于了解程序所需的闸明性资料。来自P37 程序必须安装入机器内部才能工作&#xff0c;文档一般是给人看的&#xff0c;不一定安装入机器。来自P37 计算机的某些功能既可以由硬件…

【日常】爬虫技巧进阶:textarea的value修改与提交问题(以智谱清言为例)

序言 记录一个近期困扰了一些时间的问题。 我很喜欢在爬虫中遇到问题&#xff0c;因为这意味着在这个看似简单的事情里还是有很多值得去探索的新东西。其实本身爬虫也是随着前后端技术的不断更新在进步的。 文章目录 序言Preliminary1 问题缘起1.1 Selenium长文本输入阻塞1.2…

vue项目本地开发完成后部署到服务器后报404

vue项目本地开发完成后部署到服务器后报404是什么原因呢&#xff1f; 一、如何部署 前后端分离开发模式下&#xff0c;前后端是独立布署的&#xff0c;前端只需要将最后的构建物上传至目标服务器的web容器指定的静态目录下即可 我们知道vue项目在构建后&#xff0c;是生成一系…

开源网安解决方案荣获四川数实融合创新实践优秀案例

​11月16日&#xff0c;2023天府数字经济峰会在成都圆满举行。本次峰会由四川省发展和改革委员会、中共四川省委网络安全和信息化委员会办公室、四川省经济和信息化厅等部门联合指导&#xff0c;聚焦数字经济与实体经济深度融合、数字赋能经济社会转型发展等话题展开交流研讨。…

航天联志Aisino-AISINO26081R服务器通过调BIOS用U盘重新做系统(windows系统通用)

产品名称:航天联志Aisino系列服务器 产品型号:AISINO26081R CPU架构&#xff1a;Intel 的CPU&#xff0c;所以支持Windows Server all 和Linux系统&#xff08;重装完系统可以用某60驱动管家更新所有硬件驱动&#xff09; 操作系统&#xff1a;本次我安装的服务器系统为Serv…

对话芯动科技 | 助力云游戏 4K级服务器显卡的探索与创新

2021年芯动科技推出了基于IMG BXT GPU IP的风华1号显卡。单块风华1号显卡可在台式机和云游戏中实现4K级别的性能&#xff0c;渲染能力达到5 TFLOPS&#xff0c;如果在服务器中同时运行两块显卡&#xff0c;性能还可翻倍。该显卡是为不断扩大的安卓云游戏市场量身定制的&#xf…

时序预测 | Python实现ConvLSTM卷积长短期记忆神经网络股票价格预测(Conv1D-LSTM)

时序预测 | Python实现ConvLSTM卷积长短期记忆神经网络股票价格预测(Conv1D-LSTM) 目录 时序预测 | Python实现ConvLSTM卷积长短期记忆神经网络股票价格预测(Conv1D-LSTM)预测效果基本介绍程序设计参考资料预测效果 基本介绍 时序预测 | Python实现ConvLSTM卷积长短期记忆神…

智能指针面试题

智能指针被问到的概率还是很大的&#xff0c;特别是Shared_ptr&#xff0c;最好会手撕&#xff0c;亲身经历&#xff01; 基本概念 1. RAll RAII&#xff08;Resource Acquisition Is Initialization&#xff09;是一种利用对象生命周期来控制程序资源&#xff08;如内存、文…

解决Requests中使用httpbin服务器问题:自定义URL的实现与验证

问题背景 在使用Python的Requests模块进行单元测试时&#xff0c;可能会遇到无法使用本地运行的httpbin服务器进行测试的问题。这是因为测试脚本允许通过环境变量HTTPBIN_URL指定用于测试的本地httpbin实例&#xff0c;但在某些测试用例中&#xff0c;URL是硬编码为httpbin.or…

100套Axure RP大数据可视化大屏模板及通用组件库

106套Axure RP大数据可视化大屏模板包括了多种实用美观的可视化组件库及行业模板库&#xff0c;行业模板涵盖&#xff1a;金融、教育、医疗、政府、交通、制造等多个行业提供设计参考。 随着大数据的发展&#xff0c;可视化大屏在各行各业得到越来越广泛的应用。可视化大屏不再…

基于共生生物算法优化概率神经网络PNN的分类预测 - 附代码

基于共生生物算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于共生生物算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于共生生物优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

02-1解析xpath

我是在edge浏览器中安装的xpath&#xff0c;需要安装的朋友可以参考下面这篇博客最新版edge浏览器中安装xpath插件 一、xpathd的使用 安装lxml pip install lxml ‐i https://pypi.douban.com/simple导入lxml.etree from lxml import etreeetree.parse() 解析本地文件 htm…

11月最新版付费进群源码自动定位+开源

感觉这个和前几天发布的付费进群差不多。 但有部分地方不一样&#xff0c;也是有什么分销分站后台&#xff0c;看见就头大。 没测试具体功能&#xff0c;可以搭建出来&#xff0c;D盾也未检测到加密文件 更多源码请到www.baicxx.com

OpenCV技术应用(4)— 如何改变图像的透明度

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教你如何改变图像的透明度&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.实现代码 &#x1f680;1.技术介绍 改变图像透明度的实…

(论文阅读40-45)图像描述1

40.文献阅读笔记&#xff08;m-RNN&#xff09; 简介 题目 Explain Images with Multimodal Recurrent Neural Networks 作者 Junhua Mao, Wei Xu, Yi Yang, Jiang Wang, Alan L. Yuille, arXiv:1410.1090 原文链接 http://arxiv.org/pdf/1410.1090.pdf 关键词 m-RNN、…

金融业务系统: Service Mesh用于安全微服务集成

随着云计算的不断演进&#xff0c;微服务架构变得日益复杂。为了有效地管理这种复杂性&#xff0c;人们开始采用服务网格。在本文中&#xff0c;我们将解释什么是Service Mesh&#xff0c;为什么它对现代云架构至关重要&#xff0c;以及它是如何解决开发人员今天面临的一些最紧…

PCL_点云分割_基于法线微分分割

一、概述 PCL_点云分割_基于法线微分分割_点云法向量微分-CSDN博客 利用不同的半径&#xff08;大的半径、小半径&#xff09;来计算同一个点的法向量差值P。判断P的范围&#xff0c;从而进行分割。 看图理解&#xff1a; 二、计算流程 1、计算P点小半径的法向量Ns 2、计…