请注意:该功能需要联系 ZEGO 技术支持开通。
http 请求方式: POST/JSON,需使用 https。
正式环境地址:https://webapi.zego.im/cgi/start-mix?access_token=ACCESS_TOKEN
测试环境地址:https://testwebapi.zego.im/cgi/start-mix?access_token=ACCESS_TOKEN
只有部分参数在开始混流后支持动态更新,未标注的则不支持动态更新,详情请参考下表中的参数描述。
参数名 | 是否必须 | 数据类型 | 说明 |
---|---|---|---|
timestamp | 是 | int64 | 时间戳(单位:秒)。 |
id_name | 是 | string | 用户标识 (不同的混流任务 id_name 要不同)。 |
biztype | 否 | string | 业务类型 live or rtv 默认 live。 |
stream_id | 否 | string | 流名。 |
appid | 是 | uint64 | 业务侧所使用的 appid。 |
MixInput | 是 | MixInput[] | 混流输入流的信息(json 结构体格式)。 |
MixOutput | 是 | MixOutput[] | 混流输出流的信息(json 结构体格式)。 |
live_channel | 否 | string | 直播频道,即房间 id。 |
output_bg_image | 否 | string | 混流背景图,如需设置,请联系对应的技术支持。 该参数在开始混流后支持动态更新。 |
output_bg_color | 否 | int64 | 混流背景色,RGB 色,需传 10 进制的值。 该参数在开始混流后支持动态更新。 |
with_sound_level | 否 | int | 混流音浪,1:开启,0:不开启;默认值是 0。 该参数在开始混流后支持动态更新。 |
userdata | 否 | string | 用户数据,自定义的数据客户端是通过收到媒体次要信息的接口 onRecvMediaSideInfo 回调 长度限制:[1, 1000]单位字节,建议小于 850 字节。 该参数在开始混流后支持动态更新。 |
seq | 是 | int | 混流请求的序号,保证混流请求被执行的顺序,自增唯一。 |
watermark | 否 | WaterMarkConfig | 水印结构(json 结构体格式),如需设置,请联系对应的技术支持。 |
task_id | 否 | string | 混流任务 id,同一个混流任务的 task_id 必须唯一,不同混流任务传入不同的 task_id,不同混流任务的时候 task_id 必须填写,同个混流任务可不填(客户自定义,务必保证唯一)。 |
audio_channel_cnt | 否 | int32 | 音频通道数,默认0:单声道,1:单声道,2:双声道。 |
testenv | 否 | int | 测试标识。 |
version | 否 | int | 版本号:1。 |
bypass | 否 | uint32 | 是否启用单流透传开关(默认不启用) 1:启用,0:不启用。 |
extra_params | 否 | ExParams[] | 额外参数(json 结构体格式),具体联系技术支持,比如 video_encode/sei_mode,可参见数据示例。 |
参数名 | 是否必须 | 数据类型 | 说明 |
---|---|---|---|
url | 是 | string | 输入流地址。 |
stream_id | 是 | string | 输入流名,URL 和流 ID 两者取其一即可,如填写了流 id,则 url 为空。 |
sound_level_id | 否 | int | 启用音浪的时候用于标记唯一用户。 |
content_control | 否 | int | 内容控制。0:取音视频,1:取音频(未实现),2:取视频。 该参数在开始混流后支持动态更新。 |
rect | 是 | RectInfo | 流的位置信息(json 结构体格式)。 |
render_mode | 否 | int | 混流输入填充模式(默认为裁剪模式)。0:裁剪模式,1:填充模式。 |
参数名 | 是否必须 | 数据类型 | 说明 |
---|---|---|---|
layer | 否 | int | 图层层次。 该参数在开始混流后支持动态更新。 |
top | 是 | int | 上边框,纯音频混流的时候,推荐填写 0。 该参数在开始混流后支持动态更新。 |
left | 是 | int | 左边框,纯音频混流的时候,推荐填写 0。 该参数在开始混流后支持动态更新。 |
bottom | 是 | int | 下边框,纯音频混流的时候,推荐填写 1。 该参数在开始混流后支持动态更新。 |
right | 是 | int | 右边框,纯音频混流的时候,推荐填写 1。 该参数在开始混流后支持动态更新。 |
参数名 | 是否必须 | 数据类型 | 说明 |
---|---|---|---|
stream_id | 是 | string | 输出流名。 |
mixurl | 是 | string | 输出流地址,URL 和流 ID 两者取其一即可,如填写了流 id,则 url 为空。 |
bitrate | 是 | int | 视频码率,纯音频混流的时候,推荐填写1。 该参数在开始混流后支持动态更新。 |
fps | 是 | int | 视频帧率,纯音频混流的时候,推荐填写 1;最大帧率默认限制在 20 帧以内,如果需要输出更大帧率,请联系 ZEGO 技术支持进行配置。 |
height | 是 | int | 画布高–视频输出分辨率高,纯音频混流的时候,推荐填写 1。 该参数在开始混流后支持动态更新。 |
width | 是 | int | 画布宽–视频输出分辨率宽,纯音频混流的时候,推荐填写 1。 该参数在开始混流后支持动态更新。 |
audio_enc_id | 否 | int | 音频编码 0:HE_AAC,1:LC_AAC,2:MP3。 |
audio_bitrate | 否 | int | 混流输出音频码率,默认 48K。 |
audio_channel_cnt | 否 | int | 音频通道数 0:单声道,1:单声道,2:双声道。 |
encode_mode | 否 | int | 混流输出码率控制模式,0 表示 CBR 恒定码率,1 表示 CRF 恒定质量,默认值为 0。 |
encode_qua | 否 | int | 视频质量参数:[0, 51],不指定时默认 23。0 最好,51 最差。 |
参数名 | 是否必须 | 数据类型 | 说明 |
---|---|---|---|
image | 是 | string | 水印图片。URL 图片大小限制需在 5MB 以内,超过 5MB 设置将不会生效。 该参数在开始混流后支持动态更新。 |
rect | 是 | RectInfo | 水印布局(json结构体格式)。 该参数在开始混流后支持动态更新。 |
参数名 | 是否必须 | 数据类型 | 说明 |
---|---|---|---|
top | 是 | int | 上边框,该值不能为奇数。 |
left | 是 | int | 左边框,该值不能为奇数。 |
bottom | 是 | int | 下边框,该值不能为奇数。 |
right | 是 | int | 右边框,该值不能为奇数。 |
参数名 | 是否必须 | 数据类型 | 说明 |
---|---|---|---|
key | 是 | string | key值。 |
value | 是 | string | value值。 |
{
"timestamp":1562052086,//时间戳;必填
"id_name": '', // 用户标识;必填
"live_channel": '', // 房间标识;可缺省
"appid": 400840168,//appid;必填
"output_bg_image":'', //混流背景图,如没有就为空;混流背景图,支持预设图片,如 (preset-id://xxx.jpg/png);此值由zego提供,开发者先将背景图提供给zego,zego设置后再反馈背景图片的设置参数;可缺省
"with_sound_level": 0, // 混流音浪,1: 开启,0:不开启;默认值是0;可缺省
"output_bg_color": '', // 混流背景色,如没有就为空;混流背景颜色,前三个字节为 RGB,即 0xRRGGBBxx;例如:选取RGB为 #FFFFFF00(白色)把#后面的16进制转成10进制,所以转换后传4294967040这个值,数值类型是整型;可缺省
"userdata": "", // 用户数据,userData自定义的数据客户端是通过收到媒体次要信息的接口 onRecvMediaSideInfo 回调,如没有就为空;可缺省
"seq": 1, // 混流请求的序号,保证混流请求被执行的顺序,自增唯一;可缺省
"task_id":"mult_output_task_id",// 混流任务id;可缺省;但多个混流任务的时候必须填写(客户自定义,务必保证唯一)
"version":1 // 默认是1
"MixInput":[//输入流列表;必填
{
"url":"stream1_url", //输入流1拉流URL,如没有就为空;必填
"stream_id":"stream1",//流ID,URL和流ID两者取其一即可,如填写了流id,则url为空;必填
"sound_level_id": 0, // 设置音浪ID,用于标识用户,soundLevelID必须 >= 0 且 <= 4294967295L(即2^32-1);可缺省
"content_control": 0, // 内容控制;0:取音视频,2:取视频,默认值是0;可缺省
"rect": { //流的位置信息;必填
"layer":0,//可缺省
"top":0,//必填
"left":0,//必填
"bottom":640,//必填
"right":480//必填
// 原点在左上角,top/bottom/left/right 定义如下:
//
// (left, top)-----------------------
// | |
// | |
// | |
// | |
// -------------------(right, bottom)
},
"render_mode": 0 // 混流输入填充模式,0:裁剪模式,1:填充模式;默认值为0;可缺省
},
{
"url":"stream2_url",//输入流2拉流URL,如没有就为空
"stream_id":"stream2",//流ID,URL和流ID两者取其一即可,如填写了流id,则url为空
"rect":{ //流的位置信息
"top":480,
"left":320,
"bottom":640,
"right":480
}
}
],
"MixOutput":[//输出流列表;必填
{
//流ID,URL和流ID两者取其一即可,如填写了流id,则url为空;必填
"stream_id": "mix_stream1",
// 输出流推流URL;如果没有则为空;必填
"mixurl":"mixurl1",
// 混流输出视频码率;必填;
// 视频码率值范围<= 10M,此参数单位是 bps,1M = 1 * 1000 * 1000 bps
"bitrate":400000,
// 混流输出视频帧率;必填;最大帧率默认限制在 20 帧以内,如果需要输出更大帧率,请联系 ZEGO 技术支持进行配置;根据网络情况设定值,帧率越高画面越流畅
"fps":15,
// 混流输出视频分辨率高;必填;不确定用什么分辨率时可采用16:9的规格设置
//此值必须≥输入流列表中bottom的最大值
"height":640
// 混流输出视频分辨率宽;必填;不确定用什么分辨率时可采用16:9的规格设置
//此值必须≥输入流列表中right的最大值
"width":480,
// 混流输出音频编码格式,默认值为 0;可缺省
// 可选值为 0:默认编码;1:可选编码
"audio_enc_id": 0,
// 混流输出音频码率,码率范围值是[10000, 192000];可缺省
// 若audio_enc_id采用默认音频编码0,采用 1/2声道时,建议码率值是 48k/64k,可根据需要在此基础上调整;
// 若audio_enc_id采用可选音频编码1,采用 1/2声道时,建议码率值是 80k/128k,可根据需要在此基础上调整
"audio_bitrate": 64000,
// 混流声道数, 1-单声道,2-双声道,默认为单声道;可缺省
"audio_channel_cnt": 1,
// 混流输出码率控制模式,0 表示 CBR 恒定码率,1 表示 CRF 恒定质量,默认值为 0;可缺省
// CRF 恒定质量 表示保证视频的清晰度在固定水平上,因此若采用此控制模式,码率会根据网速的变化波动,比如游戏类直播时,为了让观众看到比较流畅的操作类画面会使用恒定质量模式,提升视频质量
"encode_mode": 0,
// 混流输出质量,输出码率控制模式参数设置为 CRF恒定质量时此设置值有效,有效值范围 [0,51],默认值是 23;可缺省
// 若想视频质量好点,在23的基础上降低质量值测试调整;若想文件大小小一点,在23的基础上升高质量值测试调整
// 以 x 值下的文件大小为例, x + 6 下的文件大小是 x 值下文件大小的一半,x - 6 下的文件大小是 x 值下 文件大小的两倍
"encode_qua": 23,
},
//如果有混流输出N路流的需求,可继续填写第N路流的输出信息
{
"stream_id": "mix_stream2", //流ID
"mixurl":"mixurl2", // 输出流推流URL
"bitrate":400000, // 混流输出视频码率
"fps":15, // 混流输出视频帧率;最大帧率默认限制在 20 帧以内,如果需要输出更大帧率,请联系 ZEGO 技术支持进行配置
"height":640,// 混流输出视频分辨率高
"width":480,// 混流输出视频分辨率宽
}
],
"watermark":{//水印位置;可缺省
"image":"iamge-id",//(preset-id://xxx.jpg/png)请联系技术支持设置
"rect":{
"top":0,
"bottom":10,
"left":0,
"right":10
}
},
"extra_params":[
{
"key":"video_encode", // 视频编码格式
"value":"h265" //h265即选用H.265编码格式,默认H.264格式
},
{
"key":"sei_mode", //sei发送模式
"value":"1" //1代表通过单帧发送,默认通过视频帧发送
}
]
}
当需要纯音频混流的时候,推荐使用如下配置:
MixOutput.fps = 1
MixOutput.bitrate = 1
MixOutput.height = 1
MixOutput.width = 1
MixInput.rect.top = 0
MixInput.rect.left = 0
MixInput.rect.bottom = 1
MixInput.rect.right = 1
{
code : 0,
message : 'success',
data:{
"id_name": '', // 用户标识
"seq": '', // 序列号
"live_channel": '', // 房间标识
"play": [
{
"hdl_url": "http://flv.dndemo.zego.im/zego/mix_stream.flv",
"hls_url": "http://hls.dndemo.zego.im/zego/mix_stream/index.m3u8",
"rtmp_url": "rtmp://rtmp.dndemo.zego.im/zego/mix_stream",
"stream_alias": "mix_stream"
}
],
"mix_duration": 213, // 混流任务持续时长,单位为秒,更新混流任务时会返回该字段
}
}
备注:
1> 若是测试环境,输入流的流 ID 和 输出流的流 ID 需要加上 zegotest-客户appid-
前缀,不加可能会导致混流失败和拉不到混流。
2> 混流协议 id_name 字段(用户标识),用于保证用户级混流请求的串行处理。如后台混流共用同一个 id_name,可能会导致混流请求失败。
package com.zego;
import java.io.*;
import java.net.*;
import java.util.*;
import java.security.*;
import com.alibaba.fastjson.*;
public class StartMixStream {
// 发送post请求
public static String sendPost(String url, String param) {
String result = "";
try {
URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
try (
PrintWriter out = new PrintWriter(conn.getOutputStream())
){
out.print(param);
out.flush();
}
try (
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))
){
String line;
while ((line = in.readLine()) != null) {
result += "\n" + line;
}
}
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
return result;
}
//构造mixinput的数据(数组)
public static LinkedHashMap[] getMixInputData_array(String inputStreamId1, String inputStreamId2){
LinkedHashMap<String,Object> mixInput_stream1_rect_map = new LinkedHashMap<>();
mixInput_stream1_rect_map.put("layer",0);
mixInput_stream1_rect_map.put("top",0);
mixInput_stream1_rect_map.put("left",0);
mixInput_stream1_rect_map.put("bottom",640);
mixInput_stream1_rect_map.put("right",480);
LinkedHashMap<String,Object> mixInput_stream1_map = new LinkedHashMap<>();
mixInput_stream1_map.put("url","");
mixInput_stream1_map.put("stream_id",inputStreamId1);
mixInput_stream1_map.put("rect",mixInput_stream1_rect_map);
LinkedHashMap<String,Object> mixInput_stream2_rect_map = new LinkedHashMap<>();
mixInput_stream2_rect_map.put("layer",1);
mixInput_stream2_rect_map.put("top",480);
mixInput_stream2_rect_map.put("left",320);
mixInput_stream2_rect_map.put("bottom",640);
mixInput_stream2_rect_map.put("right",480);
LinkedHashMap<String,Object> mixInput_stream2_map = new LinkedHashMap<>();
mixInput_stream2_map.put("url","");
mixInput_stream2_map.put("stream_id",inputStreamId2);
mixInput_stream2_map.put("rect",mixInput_stream2_rect_map);
LinkedHashMap[] mixInput_array = {mixInput_stream1_map,mixInput_stream2_map};
return mixInput_array;
}
//构造mixoutput的数据(数组)
public static LinkedHashMap[] getMixOutputData_array(String outputStreamId, String cdnURL){
LinkedHashMap<String,Object> mixOutput_map = new LinkedHashMap<>();
mixOutput_map.put("stream_id", outputStreamId);
mixOutput_map.put("mixurl", cdnURL + outputStreamId);
mixOutput_map.put("bitrate", 400000);
mixOutput_map.put("fps", 15);
mixOutput_map.put("height", 640);
mixOutput_map.put("width", 480);
LinkedHashMap[] mixOutput_array = {mixOutput_map};
return mixOutput_array;
}
public static void main(String args[]) throws Exception{
// zego分配的appid
Long appid = 123456789L;
// 发起混流的id_name
String id_name = "xxx";
// 混流的roomid
String live_channel = "xxxx";
// 输入流的流id
String inputStreamId1 = "is1"; // 注意如果为测试环境,流id为 "zegotest-" + appid + "-is1"
String inputStreamId2 = "is2"; // 注意如果为测试环境,流id为 "zegotest-" + appid + "-is2"
// 输出的混流流id
String outputStreamId = "os"; //注意如果为测试环境,流id为 "zegotest-" + appid + "-os"
// cdn的推流地址
String cdnURL = "rtmp://127.0.0.1/xxx/";
// md5加密所需的时间戳
String timestamp = Long.toString(System.currentTimeMillis()/1000);
// 请求混流的url,注意正式环境与测试环境的区别, url中包含的access_token参考 "获取Access Token"
String startMixStream_url = "https://testwebapi.zego.im/cgi/start-mix?access_token=";
// 构造生成mixInput_str的字符串和mixOutput_str的字符串, 需要做urlencode
LinkedHashMap[] mixInput_array = getMixInputData_array(inputStreamId1, inputStreamId2);
LinkedHashMap[] mixOutput_array = getMixOutputData_array(outputStreamId, cdnURL);
LinkedHashMap<String,Object> postJsonData = new LinkedHashMap<>();
postJsonData.put("id_name", id_name);
postJsonData.put("live_channel", live_channel);
postJsonData.put("appid", appid);
postJsonData.put("MixInput", mixInput_array);
postJsonData.put("MixOutput", mixOutput_array);
String post_json_str = JSONObject.toJSONString(postJsonData);
System.out.println(post_json_str);
// 发送请求开始混流, access_token 参考 "获取Access Token" 部分
String ret = StartMixStream.sendPost(startMixStream_url + access_token, post_json_str);
System.out.println(ret);
}
}
<?php
$token = 'xxxxxxxx';
//// 注意如果为测试环境,MixInput的stream_id为 "zegotest-" + appid + "xxxxx",MixOutput的stream_id为"zegotest-" + appid + "xxxxx".
$json = '{"appid":123456789,"id_name":"xxx","live_channel":"xxxxx","audio_channel_cnt":0,"output_bg_color":0,"output_bg_image":"","output_audio_bitrate":0,"with_sound_level":0,"UserData":"","seq":0,"version":1,"MixInput":[{"url":"","stream_id":"xxxxxxxx","sound_level_id":0,"content_control":0,"rect":{"layer":0,"top":0,"left":0,"bottom":1,"right":1},"render_mode":0}],"MixOutput":[{"stream_id":"xxxxx","mixurl":"xxxxxxxx","bitrate":1,"fps":1,"height":1,"width":1,"audio_channel_cnt":0,"audio_enc_id":0,"audio_bitrate":0,"encode_mode":null,"encode_qua":null,"output_bg_color":0,"output_bg_image":""}],"task_id":"","watermark":null,"bypass":null}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_URL, 'https://testwebapi.zego.im/cgi/start-mix?access_token=' . $token);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
'Content-Length: ' . strlen($json)
)
);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = array($httpCode, $response);
print_r($result);
?>
curl -X POST http://106.15.219.49/cgi/start-mix?access_token=VlhXbXp1eWxhZFd6azZzTitTS3M0aWNGa3d3ZFRveU5FbjlRWTF4VXl6bU5EQkpQZ2l2d1ZobTdPdHo5dUd0WQ -d '{"appId": 3828875002,"id_name":"test_mix","task_id":"task1","timestamp": 1562052086,"MixInput":[{"url":"avertp://39.108.212.3/miniapp/mix-input-test-1000yanglei","rect":{"layer":1,"top":320,"left":180,"bottom":640,"right":360}}],"mixOutput":[{"mixurl":"avertp://39.108.212.3/miniapp/mix-output-test-1000yanglei","bitrate":400000,"fps":15,"height":1024,"width":840}],"output_bg_image":"preset-id://liveme-bg"}'
联系我们
文档反馈