移动云获取推拉流地址

news2024/11/16 11:32:46

一:帮助文档:

移动云帮助中心icon-default.png?t=N7T8https://ecloud.10086.cn/op-help-center/doc/category/753

二:准备工作:

1:进入移动云首页,点击【产品】>【视频服务】>【视频服务】>【视频直播】

        点击【立即订购】,会跳转到视频直播购买页面进行购买

2:根据选择订购服务的区域,确认对应的API接入地址。

3:进入控制台,选择视频点播,点击API认证消息,获取uid、secretId、secretKey备用。

三:流程说明:

1:想要获取移动云的直播推拉流地址,首先需要有一个直播频道。

这个直播频道是调用API接口 /l2/live/createChannel创建时返回的channel_Id。

使用该频道id作为参数,再去请求推流和播流的API地址,就能获得对应的推拉流地址。

参考文档:移动云帮助中心icon-default.png?t=N7T8https://ecloud.10086.cn/op-help-center/doc/article/40529

 2:无论是创建直播频道还是获取推拉流地址,都需要携带token验证字符串,API接口在收到请求时,会验证token是否有效。

所以,生成token是所有请求的必经之路。

3:官方文档推荐使用v2.0版本进行鉴权,那么,接下来我们就讲解v2.0版本的鉴权token如何生成。参考文档:

移动云帮助中心icon-default.png?t=N7T8https://ecloud.10086.cn/op-help-center/doc/article/40526

请注意:生成鉴权token时,需要根据每个业务接口文档的GET和POST请求方式不同而给签名body赋予不同的值。下面是官方文档中需要注意事项,特别之处已经标注出来。

四:代码实现:

/**
    * 生成移动云鉴权token
    * $business_arr 业务参数列表
    * $request_type 请求方式 get/post 默认get
    */
   function getEcloudToken($business_arr,$request_type='get'){
   		$rs=[];
   		
   		$uid=;
   		$secretId=;
   		$secretKey=;
   		$apiId=200001;
   		
   		$currentTimeStamp=getMillisecond();
   		$expired=$currentTimeStamp+12*60*60*1000;
   		$grant_type='v2.0';
   		$random=sprintf("%08d",rand(0,99999999));


   		$arr=[
   			'apiId'=>$apiId,
   			'body'=>'%5B%5D',
   			'currentTimeStamp'=>$currentTimeStamp,
   			'expired'=>$expired,
   			'grant_type'=>$grant_type,
   			'random'=>$random,
   			'secretId'=>$secretId,
   			'uid'=>$uid
   		];

   		if($request_type=='post'){
   			$body_str = rawurlencode(json_encode($business_arr));
   			
   			$arr['body']=$body_str;

   		}else{
   			$arr=array_merge($arr,$business_arr);
   		}

   		//var_dump($request_type."参与token生成的参数");
   		//var_dump($arr);


   		//var_dump("业务参数");
   		//var_dump($business_arr);

   		ksort($arr);//按照字典排序参数数组

   		//var_dump("字典排序后的参数");
   		//var_dump($arr);

   		$sign = "";
   		foreach ($arr as $k => $v) {
   			
   			$sign .= $k."=".$v."&";
   		}

   		$new_sign = mb_substr($sign, 0,mb_strlen($sign)-1);

   		//var_dump("拼接的字符串");
   		//var_dump($new_sign);
   		

   		$token = hash_hmac('sha256', $new_sign, $secretKey);

   		//var_dump("生成的token");
   		//var_dump($token);

   		$rs=[];

   		unset($arr['body']);

   		$arr['token']=$token;


		//拼接基础参数字符串
		
   		ksort($arr);//按照字典排序参数数组
   		$raw_sign = "";
   		foreach ($arr as $k => $v) {
   			
   			$raw_sign .= $k."=".$v."&";
   		}

   		$new_raw_sign = mb_substr($raw_sign, 0,mb_strlen($raw_sign)-1);

   		$rs['raw_sign']=$new_raw_sign;
   		
   		return $rs;
   		
   }
//生成毫秒级时间戳
   	function getMillisecond() {
	  list($s1, $s2) = explode(' ', microtime());
	  return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
	}
//字符串中的中文转unicode
	function chnToUnicode($str){
	    $unicode = '';
	    for ($i = 0; $i < mb_strlen($str); $i++){
	        $char = mb_substr($str, $i, 1);
	        if($char >=19968 && $char <=171941){
	        	$unicode .= '\\u' . str_pad(bin2hex(iconv('UTF-8', 'UCS-2', $char)), 4, '0', STR_PAD_LEFT);
	        }else{
	        	$unicode .= $char;
	        }
	        
	    }
	    return $unicode;
	}
//post提交
   function curl_post($url,$params){

   		$rs=['code'=>0,'msg'=>'','info'=>[]];

   		$ch = curl_init();    // 启动一个CURL会话
		curl_setopt($ch, CURLOPT_URL, $url);     // 要访问的地址
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  // 对认证证书来源的检查   // https请求 不验证证书和hosts
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  // 从证书中检查SSL加密算法是否存在
		//curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
		//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
		//curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
		curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
		curl_setopt($ch, CURLOPT_POSTFIELDS, $params);     // Post提交的数据包
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);     // 设置超时限制防止死循环
		curl_setopt($ch, CURLOPT_TIMEOUT, 10);
		$header=['Content-Type: application/json'];
		curl_setopt($ch, CURLOPT_HTTPHEADER, $header); // 设置请求头部信息
		//curl_setopt($ch, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     // 获取的信息以文件流的形式返回 
		$result = curl_exec($ch);

		//var_dump("POST请求的返回结果");
		//var_dump($result);

		if(curl_errno($ch)){
		    $rs['code']=1001;
			$rs['msg']='请求失败';
			return $rs;
		}

		if(!isJsonString($result)){
			$rs['code']=1002;
			$rs['msg']=$result;
			return $rs;
		}

		$result_arr = json_decode($result,true);

		if($result_arr['ret']==0 && $result_arr['msg']=='success'){

			$rs['info'][0]=$result_arr['result'];

			return $rs;

		}else{
			$rs['code']=1003;
			$rs['msg']=$result;
			return $rs;
		}

		curl_close($ch);
   }

   //get提交
   function curl_get($url){

   		$rs=['code'=>0,'msg'=>'','info'=>[]];

	    $header = array(
	       'Content-Type: application/json',
	    );
	    $curl = curl_init();
	    //设置抓取的url
	    curl_setopt($curl, CURLOPT_URL, $url);
	    //设置头文件的信息作为数据流输出
	    curl_setopt($curl, CURLOPT_HEADER, 0);
	    // 超时设置,以秒为单位
	    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
	 
	    // 超时设置,以毫秒为单位
	    // curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);
	 
	    // 设置请求头
	    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
	    //设置获取的信息以文件流的形式返回,而不是直接输出。
	    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
	    //执行命令
	    $result = curl_exec($curl);
	 
	    // 显示错误信息
	    if (curl_error($curl)) {

	        $rs['code']=1001;
			$rs['msg']='请求失败';
			return $rs;
	    }

	    //var_dump("GET请求的返回结果");
		//var_dump($result);

	    if(!isJsonString($result)){
			$rs['code']=1002;
			$rs['msg']=$result;
			return $rs;
		}

		$result_arr = json_decode($result,true);

		if($result_arr['ret']==0 && $result_arr['msg']=='success'){

			$rs['info'][0]=$result_arr['result'];

			return $rs;

		}else{
			$rs['code']=1003;
			$rs['msg']=$result;
			return $rs;
		}

	    curl_close($curl);
	}


   /**
     * 校验json字符串
     * @param string $stringData 
     * @return bool
     */
    function isJsonString($stringData){

        if (empty($stringData)) return false;

        try{
            //校验json格式
            json_decode($stringData, true);
            return JSON_ERROR_NONE === json_last_error();
        }
        catch (\Exception $e)
        {
            return false;
        }
    }
/**
	*  @desc 移动云推拉流地址
	*  @param string $stream 流名
	*  @param int $type 类型,0表示播流,1表示推流
	*/
	function PrivateKey_ecloud($stream,$type){

		
		$api_url='https://api.migucloud.com'; //根据自己应用所在区域进行更换
		$stream_arr = explode('_',$stream);
		$liveuid=$stream_arr[0];
		$starttime=$stream_arr[1];

		//推流
		if($type==1){

			//1:创建直播
			$param=[
				'title'=>'用户'.$liveuid,
				'startTime'=>date('Y-m-d H:i:s',$starttime),
				'endTime'=>date('Y-m-d H:i:s',$starttime+30*24*60*60),
				'subject'=>'用户'.$liveuid.'直播',
				'record'=>0,
				'playMode'=>0,
				'cdnType'=>0,

			];


			//获取签名token
			$result_arr = getEcloudToken($param,'post');

			//var_dump("请求签名后返回的参数");
			//var_dump($result_arr);
			
			$createroom_method='/l2/live/createChannel';

			//带基础参数
			$request_url=$api_url.$createroom_method.'?'.$result_arr['raw_sign'];
			

			//var_dump("请求创建直播接口的地址");
			//var_dump($request_url);

			$param['title']=chnToUnicode($param['title']);
			$param['subject']=chnToUnicode($param['subject']);

			//var_dump("进行POST请求时,传递的业务参数:");
			//var_dump($param);
			
			$result = curl_post($request_url,json_encode($param));

			if($result['code'] !=0){
				$url='';
				return $url;
			}

			$channelId=$result['info'][0]['channelId'];

			//var_dump("直播频道id");
			//var_dump($channelId);

			//2:获取推流地址
			$param=[
				'channel_id'=>$channelId
			];

			//获取签名token
			$result_arr = getEcloudToken($param,'get');

			$getpushurl_method='/l2/addr/getPushUrl';

			//带基础参数
			$request_url=$api_url.$getpushurl_method.'?'.$result_arr['raw_sign'];

			//var_dump("请求获取推流接口的地址");
			//var_dump($request_url);

			$result = curl_get($request_url);

			if($result['code'] !=0){
				$url='';
				return $url;
			}

			$push_url=$result['info'][0]['cameraList'][0]['url'];

			//var_dump("推流地址");
			//var_dump($push_url);
			return ['channel_id'=>$channelId,'push_url'=>$push_url];


		//播流
		}else{


			$channel_id=''; //创建直播接口返回的channelId

			$param=[
				'channel_id'=>$channel_id
			];

			//获取签名token
			$result_arr = getEcloudToken($param,'get');

			//var_dump("请求签名后返回的参数");
			//var_dump($result_arr);

			$getpullurl_method='/l2/addr/getPullUrl';

			//带基础参数
			$request_url=$api_url.$getpullurl_method.'?'.$result_arr['raw_sign'];

			//var_dump("请求获取播流接口的地址");
			//var_dump($request_url);

			$result = curl_get($request_url);

			if($result['code'] !=0){
				$url='';
				return $url;
			}

			$pull_url=$result['info'][0]['cameraList'][0]['transcodeList'][0]['urlRtmp'];

			//var_dump("播流地址");
			//var_dump($pull_url);

			return $pull_url;
		}


	} 
//删除直播
function removeChannel($channel_id){
    
    $param=['id'=>$channel_id];

	$result_arr = getEcloudToken($param,'post');

	$removechannel_method='/l2/live/removeChannel';

	$api_url='https://api.migucloud.com'; //根据自己应用所在地区替换

	$request_url=$api_url.$removechannel_method.'?'.$result_arr['raw_sign'];

	$result = curl_post($request_url,json_encode($param));

}

调用方法:

获取推流地址:

$stream='1001_1698291555';
PrivateKey_ecloud($stream,1);

返回创建开播参数截图:

截图中请求创建开播的API地址:

https://api.migucloud.com/l2/live/createChannel?apiId=200001&currentTimeStamp=1698460266645&expired=1698503466645&grant_type=v2.0&random=53415941&secretId=69a7c3a1fd52a584d8fd79a0118b8173&token=752556e89b8af7b572da0d701389d0eedb61df523a1b192a37bd608fd460b014&uid=800000234

返回获取推流地址截图:

截图中请求获取推流的API地址:

https://api.migucloud.com/l2/addr/getPushUrl?apiId=200001&channel_id=20231028103106_BNDEKC9U&currentTimeStamp=1698460266888&expired=1698503466888&grant_type=v2.0&random=08691557&secretId=69a7c3a1fd52a584d8fd79a0118b8173&token=6d9ddbab6dbc3d3d35afd051296448bddba90e2acf3ca7057c4c9bb6b3cabad9&uid=800000234

获取播流地址:

$stream='1001_1698291555';
PrivateKey_ecloud($stream,0);

返回获取播流地址截图:

截图中请求获取播流的API地址:

https://api.migucloud.com/l2/addr/getPullUrl?apiId=200001&channel_id=20231028103106_BNDEKC9U&currentTimeStamp=1698463713230&expired=1698506913230&grant_type=v2.0&random=62397059&secretId=69a7c3a1fd52a584d8fd79a0118b8173&token=b4b4a6a30621bfdc6f7f6c66a00ab1bc8588125c3b5861e430b9d21605b2c75e&uid=800000234

截图中返回的结果:

{"ret":"0","msg":"success","result":{"uid":"800000234","channelId":"20231028103106_BNDEKC9U","imgUrl":"","cdnType":0,"viewerNum":0,"urlTimeshift":null,"cameraList":[{"camIndex":"C0","transcodeList":[{"transType":"0","urlRtmp":"rtmp://devlivepull.migucloud.com/live/BNDEKC9U_C0","urlHls":"http://wshls.live.migucloud.com/live/BNDEKC9U_C0/playlist.m3u8","urlFlv":"http://devlivepull.migucloud.com/live/BNDEKC9U_C0.flv","transCode":"Wating","transDesc":"等待中"}]}]}}

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

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

相关文章

图纸管理制度 《五》

1、存档文件应由专人管理&#xff0c;其他人未征得管理人员同意&#xff0c;不得随意翻阅查看。 2、档案管理人员要认真贯彻执行公司相关制度&#xff0c;严禁泄露档案材料中的秘密。 彩虹图纸管理软件_图纸管理系统_图纸文档管理软件系统_彩虹EDM【官网】彩虹EDM图纸管理软件…

Linux进程控制/进程终止

一、系统调用fork函数 1、fork返回值及内核操作 #include <unistd.h> pid_t fork(void); 返回值&#xff1a;自进程中返回 0 &#xff0c;父进程返回子进程 id &#xff0c;出错返回 -1 进程调用fork&#xff0c;当控制转移到内核中的fork代码后&#xff0c;内核做&am…

UE4 体积云制作 学习笔记

首先Noise本来就是一张噪点图 云的扰动不能太大&#xff0c;将Scale调小&#xff0c;并将InputMin调整为0 形成这样一张扰动图 扰动需要根据材质在世界的位置进行调整&#xff0c;所以Position需要加上WorldPosition 材质在不同世界位置&#xff0c;噪点不同 除以一个数&#…

会声会影2024(Corel VideoStudio)正式版安装下载步骤教程

众所周知会声会影(Corel VideoStudio)2024为加拿大Corel公司发布的一款功能丰富的视频编辑软件。实际上我们可以这样讲添加样子和款式&#xff1a;使用数百种创意拖放效果和滤镜增个性和艺术格调。值得肯定的是添加趣味性3D标题&#xff0c;内置NewBlueFX和proDAD转场和防抖插件…

基于头脑风暴算法的无人机航迹规划-附代码

基于头脑风暴算法的无人机航迹规划 文章目录 基于头脑风暴算法的无人机航迹规划1.头脑风暴搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用头脑风暴算法来优化无人机航迹规划。 …

矩阵特征值与特征向量的理解

各位朋友大家好&#xff0c;我是小C哈哈哈&#xff0c;很高兴认识大家&#xff0c;在这里&#xff0c;我会将一些枯燥难懂的数学和算法知识以图片或动画的形式通俗易懂的展现给大家&#xff0c;希望大家喜欢。 线性代数中的矩阵特征值与特征向量这两个基本概念总是让很多人摸不…

接口自动化框架篇:流程封装与基于加密接口的测试用例设计

​接口测试仅仅掌握 Requests 或者其他一些功能强大的库的用法&#xff0c;是远远不够的&#xff0c;还需要具备能根据公司的业务流程以及需求去定制化一个接口自动化测试框架的能力。所以&#xff0c;接下来&#xff0c;我们主要介绍下接口测试用例分析以及通用的流程封装是如…

nginx配置域名(ssl和非ssl形式)

概要 本文以阿里云为例&#xff0c;浅要介绍如何将域名指向你的服务器&#xff0c;以及如何配置ssl和非ssl的方式。 购买域名 购买域名不做描述&#xff0c;本文域名以helloword.com为例 域名实名与备案 购买后&#xff0c;不实名和备案是无法使用的&#xff0c;这里不展开…

Games 103 作业二

Games 103 作业二 作业二其实就是要使用隐式积分和PBD两种方式来实现布料求解。难度相对于作业一来说要简单一些&#xff0c;在文档中基本把步骤都写清楚了。主要逻辑首先参考Lecture 05 PPT的第18页&#xff1a; 然后我们按照文档的步骤一步一步地来。注意0号顶点和20号顶点是…

JSX基础语法

文章目录 认识JSX语法JSX是什么为什么Rect选择了JSXJSX书写规范JSX注释编写 JSX的基本使用JSX的事件绑定this绑定问题参数传递问题 JSX的条件渲染常见的条件渲染方式 JSX的列表渲染JSX的原理和本质JSX的本质虚拟DOM的创建过程 案例练习 认识JSX语法 // 1. 定义根组件 const el…

【Truffle】一、Truffle的安装与部署

目录 一、准备安装 二、安装truffle 三、创建 Truffle 项目工程 1.为 Truffle 项目创建新目录&#xff1a; 2.下载 (“unbox”) MetaCoin box: 四、项目分析 五、测试合约 一、准备安装 安装truffle必须要提前配置Nodejs环境&#xff0c;关于Nodejs的配置&#xff0c;我在…

黑豹程序员-架构师学习路线图-百科:Lombok消除冗长的java代码

文章目录 1、为什么要使用Lombok&#xff1f;2、Lombok的工作原理3、反对声渐渐消亡4、总结4.1、什么是Lombok&#xff1f;4.2、Lombok的发展历史4.3、Lombok常见的注解 1、为什么要使用Lombok&#xff1f; 现代的java项目开发都使用分层开发&#xff0c;MVC分层已经深入人心&…

Vue组件自定义事件实现子组件给父组件传递数据

一、绑定自定义事件 &#xff08;一&#xff09;使用v-on或绑定事件 事件是绑定在组件身上的&#xff0c;当我们触发这个事件的时候&#xff0c;就会执行事件回调函数。 <组件标签 v-on:事件名"事件回调函数"/> // 或 <组件标签 事件名"事件回调函…

文心一言 VS 讯飞星火 VS chatgpt (122)-- 算法导论10.4 3题

三、用go语言&#xff0c;给定一个n结点的二叉树&#xff0c;写出一个 O(n)时间的非递归过程&#xff0c;将该树每个结点的关键字输出。可以使用一个栈作为辅助数据结构。 文心一言&#xff1a; 以下是一个使用 Go 语言编写的函数&#xff0c;该函数使用一个栈作为辅助数据结…

Web应用系统设计

Web应用设计的本质目的是为了解决软件系统的复杂性,所以我们在进行web设计时,首先要分析系统的复杂性,然后再进行设计。 1.案例 某公司在创业初期快速地开发了一个B2C的垂直电商网站,然后就迅速的投向市场进行运营。为了能够快速上线,系统设计得非常简单,选择了三层架构…

大厂面试题-Java并发编程基础篇(一)

目录 一、什么是守护线程&#xff0c;它有什么特点 二、谈谈你对AQS的理解 三、AbstractQueuedSynchronized为什么采用双向链表 四、lock和synchronized区别 五、线程池如何知道一个线程的任务已经执行完成 六、什么叫做阻塞队列的有界和无界 七、ConcurrentHashMap底层…

拓扑排序基础详解,附有练习题

介绍 拓扑排序是一种对有向无环图&#xff08;DAG&#xff09;进行排序的算法。在一个有向图中&#xff0c;如果存在一条从节点 A 到节点 B 的路径&#xff0c;那么节点 A 就依赖于节点 B。 有向无环图如下 什么是入度&#xff0c;出度&#xff1f; 入度&#xff1a;有多少个…

10款轻量型的嵌入式GUI库分享

LVGL LittlevGL是一个免费的开源图形库&#xff0c;提供了创建嵌入式GUI所需的一切&#xff0c;具有易于使用的图形元素、漂亮的视觉效果和低内存占用。 特点&#xff1a; 强大的构建模组 按钮、图表、列表、滑块、图像等 ​先进的图形 动画、反锯齿、半透明、平滑滚动 多样…

【VR开发】【Unity】【VRTK】1-无代码VRVR开发介绍

本篇开始精简讲解VRTK相关的知识。 VRTK是基于Unity的一套提供无代码VR开发的插件,这套插件开源,可商用,集合了目前可能的VR体验组件,可以让不会C#编程但想要开发VR体验的人在不写一行代码的前提下开发出心仪的VR作品。 这套组件问世后也很受欢迎,目前已经进化到了第四代…

2023阿里云双十一优惠活动「云上聚·创未来」价格和代金券领取

2023阿里云双十一优惠活动「金秋云创季」开始啦&#xff0c;10月27日到10月31日可以领满减优惠&#xff0c;到11月1日和11月11日之间可以购买云服务器等产品&#xff0c;11.12到11.30日赢最高百万上云抵扣金&#xff0c;阿里云百科aliyunbaike.com分享2023阿里云双十一优惠活动…