web端使用PHP实现【云端混流】,暂实现了2人,写篇文章记录下

2019-11-14 17:26:31 浏览数 (1)

阅读对象:仅适用于web端开发者,参见官方提示:

仅适用REST API仅适用REST API

一、常用的网址:

  • 实时音视频:https://console.cloud.tencent.com/trtc
  • 云端混流:https://cloud.tencent.com/document/product/267/8832
  • 云直播:https://cloud.tencent.com/document/product/267/30148

官方提示录制的混流结果,在这个文档中获取,目前还没拿到记录

  • CDN旁路直播:https://cloud.tencent.com/document/product/647/16826
      仅看流ID生成的规则,拼接混流参数会用到。 仅看流ID生成的规则,拼接混流参数会用到。

二、云端混流的URL传递鉴权参数说明

满足混流的条件,房间同时在线人数> = 2

官方文档:

参数位置:

appid和生成sign参数用到的Api鉴权KEY:

实时音视频应用页->账号信息->直播信息处

appid和api鉴权key

代码:appid和API鉴权key,写在了env和config中。

代码语言:javascript复制
   
   $sUrlParamT = time()   60;
        $aUrlParams = [
            'appid'     =>   env('TRTC_APPID'),
            'interface' =>   'Mix_StreamV2',
            't'         =>   $sUrlParamT,
            'sign'      =>   md5(env('TRTC_AUTHENTICA_API_KEY') . $sUrlParamT)
        ];

        //构建请求URL   参数
        $sRequestUrl = config('mixstream.request_api') . '?' . http_build_query($aUrlParams);

三、PHP代码,使用laravel的框架,前端为音视频小程序,目前用postman请求的后台,为了测试混流。没有和音视频小程序去做API,思路是先实现云端混流,参考官方提供python代码【demo_template_310.py】,php代码:

路由:

代码语言:javascript复制
Route::group(['namespace' => 'Api', 'prefix' => 'api'], function () {
    Route::group(['middleware' => 'api'], function () {
        Route::post('webrtc/mix_stream', 'WebrtcController@beginMixStream');//开始混流
        Route::post('webrtc/end_mix_stream', 'WebrtcController@endMixStream');//结束混流
    });
});

控制器,两个方法,分别是开始混流、结束混流,使用了构造方法,依赖注入的oWxMixStreamService服务。

代码语言:javascript复制

    /**
     * 混流操作
     */
    public function beginMixStream(Request $oRequest)
    {
        $this->oWxMixStreamService->beginMixStream($oRequest->input('roomId'), '写死了主播的流ID');
    }

    /**
     * 结束混流
     */
    public function endMixStream(Request $oRequest)
    {
        $this->oWxMixStreamService->endMixStream($oRequest->input('roomId'), '写死了主播的流ID');
    }

oWxMixStreamService服务代码

代码语言:javascript复制
<?php

namespace AppServices;

use GuzzleHttpClient;
use Log;

class WxMixStreamService
{
    public static function beginMixStream($iRoomId, $sStreamId)
    {
        //构建URI鉴权参数
        $sUrlParamT = time()   60;
        $aUrlParams = [
            'appid'     =>   env('TRTC_APPID'),
            'interface' =>   'Mix_StreamV2',
            't'         =>   $sUrlParamT,
            'sign'      =>   md5(env('TRTC_AUTHENTICA_API_KEY') . $sUrlParamT)
        ];

        //构建请求URL   参数
        $sRequestUrl = config('mixstream.request_api') . '?' . http_build_query($aUrlParams);
        Log::info($sRequestUrl);

        //请求的参数
        $aRequestParmas = [
            'timestamp' => time(),
            'eventId'   => mt_rand(10000000, 2100000000),
            'interface' => [
                'interfaceName' => 'Mix_StreamV2',
                'para'          => [
                    'interface' => 'mix_streamv2.start_mix_stream_advanced',
                    'app_id' => env('TRTC_APPID'),
                    'mix_stream_template_id' => 30,
                    'mix_stream_session_id' => $iRoomId,
                    'output_stream_id'  => $sStreamId,
                    'input_stream_list'  => [
                        [
                            'input_stream_id' => $sStreamId,
                            'layout_params'   => [
                                'image_layer' => 1,
                            ],
                        ],
                        [
                            'input_stream_id' => '写死了观众的流',
                            'layout_params'   => [
                                'image_layer' => 2,
                            ],
                        ]
                    ]
                ]
            ]
        ];
        //使用guzzleClient扩展,很重要的一点,请求头需要包含Content - Type 为 application/json
        $oRequestClient = new Client();
        $oResponse = $oRequestClient->request('POST', $sRequestUrl, [
            'json' => $aRequestParmas,
        ]);
        Log::info($oResponse->getBody()->getContents());
    }

    //结束混流
    public function endMixStream($iRoomId, $sStreamId)
    {
        //构建URI鉴权参数
        $sUrlParamT = time()   60;
        $aUrlParams = [
            'appid'     =>   env('TRTC_APPID'),
            'interface' =>   'Mix_StreamV2',
            't'         =>   $sUrlParamT,
            'sign'      =>   md5(env('TRTC_AUTHENTICA_API_KEY') . $sUrlParamT)
        ];

        //构建请求URL   参数
        $sRequestUrl = config('mixstream.request_api') . '?' . http_build_query($aUrlParams);
        //请求的参数
        $aRequestParmas = [
            'timestamp' => time(),
            'eventId'   => mt_rand(10000000, 2100000000),
            'interface' => [
                'interfaceName' => 'Mix_StreamV2',
                'para'          => [
                    'interface' => 'mix_streamv2.cancel_mix_stream',

                    'app_id' => env('TRTC_APPID'),
                    //申请混流成功后,业务需要记录该值,在取消混流时,将申请混流时的 mix_stream_session_id 填入。
                    'mix_stream_session_id' => (string) $iRoomId,

                    //输出源ID
                    'output_stream_id'  => $sStreamId,
                    ]
                ]
        ];

        Log::info($aRequestParmas);

        $oRequestClient = new Client();
        $oResponse = $oRequestClient->request('POST', $sRequestUrl, [
            'json' => $aRequestParmas,
        ]);
        Log::info($oResponse->getBody()->getContents());
    }
}

四、前端音视频小程序开发测试的流程

  • 使用微信开发者工具,使用2个手机,点击开发工具预览,后台计算出流ID
代码语言:javascript复制
   //计算流id,bizid . md5(房间id_用户名_main)
    public function streamId($iRoomId, $sUserName)
    {
        return (string) env('TRTC_BIZID') . '_' . md5($iRoomId . '_' . $sUserName . '_main');
    }
        
  • 如代码写死2个流,去调用的接口,成功失败返回的信息如下
代码语言:javascript复制
//开始混流
 {"code":0,"event_id":"1233110064","message":"Success!","timestamp":1573652147}
//结束混流
 {"code":0,"event_id":"1887094489","message":"","timestamp":1573652735}

0 人点赞