一:帮助文档:
移动云帮助中心
https://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地址,就能获得对应的推拉流地址。
参考文档:移动云帮助中心
https://ecloud.10086.cn/op-help-center/doc/article/40529
2:无论是创建直播频道还是获取推拉流地址,都需要携带token验证字符串,API接口在收到请求时,会验证token是否有效。
所以,生成token是所有请求的必经之路。
3:官方文档推荐使用v2.0版本进行鉴权,那么,接下来我们就讲解v2.0版本的鉴权token如何生成。参考文档:
移动云帮助中心
https://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地址:【敏感信息已做处理】
返回获取推流地址截图:

截图中请求获取推流的API地址:【敏感信息已做处理】
获取播流地址:
$stream='1001_1698291555';
PrivateKey_ecloud($stream,0);
返回获取播流地址截图:

截图中请求获取播流的API地址:
截图中返回的结果:【敏感信息已做**处理】
{"ret":"0","msg":"success","result":{"uid":"800000234","channelId":"20231028103106_BND****U","imgUrl":"","cdnType":0,"viewerNum":0,"urlTimeshift":null,"cameraList":[{"camIndex":"C0","transcodeList":[{"transType":"0","urlRtmp":"rtmp://devlivepull.migucloud.com/live/BND****U_C0","urlHls":"http://wshls.live.migucloud.com/live/BND****U_C0/playlist.m3u8","urlFlv":"http://devlivepull.migucloud.com/live/BND****U_C0.flv","transCode":"Wating","transDesc":"等待中"}]}]}}