混流

下载pdf
更新时间:2020-01-02 19:05

1 简介

混流是把多路音视频流混合成单流的技术。

主播端和观众端均可主动触发混流。SDK 既支持音视频混流,也支持纯音频混流。

SDK 对设置混流的时机没有硬性要求,建议开发者在拉流 / 推流后,或根据需求,在其他合适时机进行混流。

请注意,由于主播端和观众端均可主动触发混流,以下步骤的操作方均为 主播端观众端。开发者在实际使用中请注意区分接口调用方

混流的主要流程是:

  1. 进入房间并推拉流。
  2. 开始混流。
  3. 将混流成功后的url地址通过后台做下发。
  4. 观众获取到url地址后进行播放

本文主要以主播端 / 观众端推流后混流为例,其他时机时设置混流的步骤类似,不再赘述。

2 步骤

按照上述流程,SDK API 调用过程如下所示。

2.1 前置条件

主播端推流后混流的前置条件为推流,请参考文档:快速开始-推流

2.1.1 混流配置参数

streamList 为输入流列表,列表中是 ZegoMixStreamInfo 对象。表示流 ID 为 streamID 的流,在输出的混流中的布局位置,根据所需的输入流个数构建N个ZegoMixStreamInfo 放入输入流列表。

注意:SDK对混流画面布局采用输入流列表中的输入流排序,按照叠放的方式布局,为了避免大布局遮挡小布局,将输入流信息放进列表时需将大布局的输入流排在小布局输入流前面;例如,想在A布局上再放一个小布局B,输入流列表就应写 ZegoMixStreamInfo[] inputStreamInfo = {streamInfoA, streamInfoB}

输入流使用示例

ZegoMixStreamInfo 的使用示例:假设指定某条流的左上角坐标为(50,300),右下角坐标为(200,450),这条流在最终的输出混流中的位置如下所示:

下面代码仅供参考:

 /**
     *  原点在左上角,top/bottom/left/right 定义如下:
     *
     *  (left, top)-----------------------
     *  |                                |
     *  |                                |
     *  |                                |
     *  |                                |
     *  -------------------(right, bottom)
     */

var streamList = [{
            streamId: _config.idName,
            top: 0,
            left: 0,
            bottom: 240,  
            right: 320,
        }];
        if (useLocalStreamList.length !== 0) {
          streamList.push({
            streamId: useLocalStreamList[0].stream_id,
            top: 240,
            left: 0,
            bottom: 480,
            right: 320,
          })  
        }    

2.1.2 输出流类型

在混流参数中,outputStreamId和 outputUrl 分别表示流输出为 url 和流名,如果需要将流推到 CDN 上,采用 url;不需要将流推到 CDN 上时,由调用者决定采用 url 或者流名。如果两个都存在,默认为 outputStreamId

2.2 开始混流

在推流成功后,调用 updateMixStream 将混流配置发送至 Zego 混流服务器,并触发混流。

注意: 当混流信息发生变更(例如,混流的输入流列表发生增减、调整混流视频输出码率等),开发者仍然需要在合适的时机调用本接口,更新Zego混流服务器上的混流配置。

demo 中演示源代码如下:

zg.updateMixStream({
            outputStreamId: mixStreamId,
            outputUrl: 'rtmp://test.aliyun.zego.im/zegodemo',
            outputBitrate: 300*1000,
            outputFps: 15,
            outputWidth: 320,
            outputHeight: 480,
            streamList: streamList
        }, function (mixStreamId, mixStreamInfo) {
            if (navigator.userAgent.indexOf('iPhone') !== -1 && getBrowser() == 'Safari') {
              hlsUrl = mixStreamInfo[0]['hlsUrls'][0].replace('http', 'https')
              $('#mixVideo')[0].src = hlsUrl
            } else {
              var flvUrl = mixStreamInfo[0]['flvUrls'][0].replace('http', 'https')
                console.log('mixStreamId: ' + mixStreamId);
                console.log('mixStreamUrl:' + flvUrl);
                alert('混流开始。。。')
                if (flvjs.isSupported()) {
                  var flvPlayer = flvjs.createPlayer({
                      type: 'flv',
                      url: flvUrl
                  });
                  flvPlayer.attachMediaElement($('#mixVideo')[0]);
                  flvPlayer.load(); 
                }
            }
            $('#mixVideo')[0].muted = false;
            $('#mixVideo').css('display', '')
        }, function (err, errorInfo) {
            alert('混流失败。。。')
            console.log('err: ' + JSON.stringify(err));
            console.log('errorInfo: ' + JSON.stringify(errorInfo));
        },);
    });

streamList 里的一个元素为输入流的参数配置,包括了streamid/ top / left / bottom / right

  • 备注: 如果要混流纯音频数据mixStreamConfig 的部分参数配置需要特殊处理:
  1. 输入流 mixStreamConfig 纯音频配置规则:top / left / bottom / right 不能全设置为 0,或全设置为 1。推荐配置:top = 0,left = 0,bottom = 1,right = 1。
  2. mixStreamConfig 纯音频配置规则:outputFps、outputBitrate 不能设置为 0。推荐配置:outputFps = 1,outputBitrate = 1,outputResolution = (1,1)。

2.3 混流配置更新通知

混流请求发送成功后,调用者可在成功回调中获取混流配置的结果及混流 ID。

常见错误码及含义如下

错误码 说明
errorCode = 150 混流的输入流不存在。请检查输入流是否正常
errorCode = 151 混流失败。请检查混流流程是否处理正常
errorCode = 152 停止混流失败。请检查混流流程是否处理正常
errorCode = 153 输入参数错误,请检查输入参数是否正确
errorCode = 154 输出参数错误,请检查输出参数是否正确
errorCode = 155 输入分辨率格式错误,请检查输入分辨率格式是否正确
errorCode = 156 输出分辨率格式错误,请检查输出分辨率格式是否正确
errorCode = 157 混流没开,请检查是否开启混流模式

2.4 停止混流

停止混流是通过调用 stopMixStream 实现。

参考代码如下:

zg.stopMixStream({
            outputStreamId: mixStreamId
        }, function () {
            console.log('stopMixStream success: ');
        }, function (err) {
            console.log('stopMixStream err: ');
        })

mixStreamConfig 对象里需填入outputStreamId 或 outputUrl
注意:开始混流和停止混流使用的mixStreamID需要保持一致。

2.5 播放混流

混流成功后拿到的播放地址格式有多种,包括flv、hlsrtmp。因hls视频格式的视频延迟较高且ios safari 不支持其它两种视频格式,建议hls格式地址仅在ios safari上使用,像chromefirefoxmac safari 等浏览器建议使用flv格式的视频格式进行播放。

在浏览器端播放flv格式视频需要用到第三方插件,下面是使用示例demo中使用 flv.js 的部分代码演示, 具体代码请参考示例代码

if (flvjs.isSupported()) {
    var flvPlayer = flvjs.createPlayer({
        type: 'flv',
        isLive: true,
        url: flvUrl // 混流成功获取到的
    });
    flvPlayer.attachMediaElement($('#mixVideo')[0]);
    flvPlayer.load(); 
}



2.6 混流转码

若出现两端编码格式的冲突,即一端只支持 H.264,一端只支持 VP8(Andriod FireFox 68 与 iOS 11 Safari)的情况,这时候建议客户使用混流转码,参考代码如下:

var mixParam = {
        outputStreamId: 'XXX',
        outputBitrate: outputBitrate ? outputBitrate * 1 : 800 * 1000,
        outputFps: 15,
        outputHeight: 480,
        outputWidth: 640,
        outputAudioConfig: videoDecodeType !== 'VP8' ? 3 : 0, // videoDecodeType 为当前编码格式
        streamList: streamList,
        extraParams: [{key: 'video_encode', value: videoDecodeType === 'VP8' ? 'h264' : 'vp8'}]
    };
    console.log('mixParam', mixParam);
    zg.updateMixStream(mixParam, function (mixStreamId, mixStreamInfo) {
        console.log('mixStreamId: ' + mixStreamId);
        console.log('mixStreamInfo: ' + JSON.stringify(mixStreamInfo));
    }, function (err, errorInfo) {
        console.log('err: ' + JSON.stringify(err));
        console.log('errorInfo: ' + JSON.stringify(errorInfo));
    });

outputAudioConfig 默认为0(可选3)。目标转码格式为 VP8 时值为3,目标转码格式为 H.264 时值为0
extraParams 需要传入一个对象,key 为'video_encode',value 为转换后的编码格式

3 混流系统架构图