本文介绍如何通过 RESTful API 实现旁路推流。
第一次使用旁路推流,需要开通服务,步骤如下:
登录控制台,在项目管理页面,选择需要开通输入旁路推流服务的项目,点击配置。
在项目配置页面选择服务配置,在旁路推流模块点击启用。
启用服务端 RESTful API。启用后不能关闭。
仔细阅读弹窗提示,点击保存。成功开启旁路推流服务后,启用按钮会切换为配置按钮,用于配置旁路推流。
开通成功后你可以在用量页面看到旁路推流的使用情况。
声网 RESTful API 要求 Basic HTTP 认证。每次发送 HTTP 请求时,都必须在请求头部填入 Authorization
字段。关于如何生成该字段的值,请参考 RESTful API 认证。
你可以使用推流 RESTful API 订阅声网频道内的音视频流,将音视频流转码后(或选择不转码),通过标准协议(如 RTMP)推送到 CDN(Content Delivery Network)。这个过程相当于声网通过一个 Converter 将音视频流处理后输出并推到 CDN。你可以通过如下方法控制 Converter:
Create
:为指定的项目创建一个 Converter,设置转码(或不转码)和推流的相关参数。频道内用户音视频流会按照指定的配置经过 Converter 处理后输出推到 CDN。Delete
:销毁指定的 Converter。销毁该 Converter 后,此频道内用户音视频流将不再经过 Converter 处理并输出推到 CDN。Update
:更新指定的 Converter 配置。Get
: 获取指定 Converter 的推流状态。POST https://api.sd-rtn.com/{region}/v1/projects/{appId}/rtmp-converters
appId
: String 型必填参数。声网为每个开发者提供的 App ID。在声网控制台创建一个项目后即可得到一个 App ID。一个 App ID 是一个项目的唯一标识。
region
: String 型必填参数。创建 Converter 的区域。声网支持分区域创建 Converter,目前支持以下区域:
cn
:中国大陆ap
:除中国大陆以外的亚洲区域na
:北美eu
:欧洲region
与你的 CDN 源站在同一个区域。region
的值为小写。regionHintIp
: String 型可选参数。CDN 源站 IP 地址,必须为有效的 IPv4 地址。该参数可以保障 RTMP 流的稳定性。
POST https://api.sd-rtn.com/{region}/v1/projects/{appId}/rtmp-converters?regionHintIp={regionHintIp}
Content-Type
: application/json
Authorization
: 该字段的值需参考认证说明。
X-Request-ID
: UUID(通用唯一识别码),标识本次请求。声网服务器会自动生成一个 UUID,并在响应 header 中返回 X-Request-ID
字段。
声网推荐你对
X-Request-ID
赋值,声网服务器会在响应 header 中返回一个X-Custom-Request-ID
字段,以用于问题排查。
旁路推流分为转码推流和不转码推流。一般来说,多人连麦直播的场景下,旁路推流时需要转码;单主播直播时,只向 CDN 推送一路媒体流,无需转码。详见功能描述。
转码推流
转码推流的请求包体为 JSON Object 类型的 converter
字段,字段结构如图所示:
字段含义详见下表:
字段 | 类型 | 描述 |
---|---|---|
name | String(可选) | Converter 的名字。长度必须在 64 个字符以内,支持的字符集范围为:409(Conflict) 。name 字段管理指定项目下的 Converter。声网推荐你以“频道名(rtcChannel )”和 “Converter 特性”组合来给 name 赋值。如 show68_horizontal 和 show68_vertical ,分别代表在频道 show68 中创建的用户画面为水平布局和和垂直布局的 Converter。 |
transcodeOptions | JSON Object(必填) | Converter 的转码配置。 |
transcodeOptions.rtcChannel | String(必填) | 声网频道名称。即 Converter 处理的流所属的频道。字符串长度必须在 64 字节以内,支持以下字符集(共 89 个字符): |
transcodeOptions.audioOptions | JSON Object | Converter 的音频转码配置。详见 audioOptions。 audioOptions 及其相关字段。audioOptions 为必填字段,若无字段要求,可以把 audioOptions 设置为空,例如:"audioOptions":{} converter.transcodeOptions.audioOptions 字段中无 rtcStreamUids 字段时,声网会将频道内所有用户的音频流进行混音并通过 Converter 输出混音后的音频流。converter.transcodeOptions.audioOptions 字段中有 rtcStreamUids 字段时,声网会将指定用户的音频流进行混音并通过 Converter 输出混音后的音频流。 |
transcodeOptions.audioOptions. codecProfile |
String(可选) | Converter 输出的音频编解码器。支持如下值:LC-AAC (默认值): MPEG-4 AAC LC。HE-AAC : High-Efficiency AAC。 |
transcodeOptions.videoOptions | JSON Object(可选) | Converter 的视频转码配置。videoOptions 及其相关字段。videoOptions 为必填字段,且不能为空。 |
transcodeOptions.videoOptions.canvas | JSON Object(必填) | 视频画布。详见 canvas。 |
transcodeOptions.videoOptions.layoutType | Number(可选) | 输出视频的画面布局类型:0 或空:(默认)自定义布局,即通过 transcodeOptions.videoOptions.layout 设置布局信息。1 :垂直布局。指定一个用户在屏幕左侧显示大视窗画面,其他用户以小视窗画面在屏幕右侧垂直排列,详见设置垂直布局。 |
transcodeOptions.videoOptions.layout | JSON Array(可选) | 画布上视频画面的内容描述。详见 layout。支持 RtcStreamView 和 ImageView 两种元素: 如果 layoutType 为0 或空,则该字段为必填。 |
transcodeOptions.videoOptions.vertical | JSON Object(可选) | 垂直布局的画面设置信息。当 layoutType 为 1 时必须设置该参数。详见 vertical。 |
transcodeOptions.videoOptions. defaultPlaceholderImageUrl |
String(可选) | 默认的用户画面背景图 URL 地址。支持 JPG、PNG 和 GIF 格式的图片。当频道内用户停止发布视频流: |
transcodeOptions.videoOptions.bitrate | Number(必填) | 输出视频的编码码率 (Kbps)。取值范围为 [1,10000]。详见常用视频属性。 |
transcodeOptions.videoOptions. frameRate |
Number(可选) | 输出视频的编码帧率 (fps)。取值范围为 [1,30]。默认值为 15。详见常用视频属性。 |
transcodeOptions.videoOptions. gop |
Number(可选) | 输出视频的 GOP。默认值为 frameRate * 2。 |
transcodeOptions.videoOptions. codec |
String(可选) | 输出视频的编解码规格。不可设置为空。支持如下值:H.264 (默认值)H.265 |
transcodeOptions.videoOptions. codecProfile |
String(可选) | 输出视频的编码规格。支持如下值:high (默认值): High 级别的视频编码规格,一般用于广播及视频碟片存储,高清电视。baseline : Baseline 级别的视频编码规格,一般用于低阶或需要额外容错的应用,比如视频通话、手机视频等。main : Main 级别的视频编码规格,一般用于主流消费类电子产品,如 mp4、便携的视频播放器、PSP 和 iPad 等。 如果 codec 设置为 H.265 ,则 codecProfile 默认且必须为 main 。 |
transcodeOptions.videoOptions.seiOptions | JSON Object(可选) | 设置输出视频中携带的用户 SEI 信息。默认为空。不设置则表示不输出 SEI 信息。详见 seiOptions。 |
idleTimeout | Number(可选) | Converter 处于空闲状态的最大时长(秒)。空闲指 Converter 处理的音视频流所对应的所有用户均已离开频道。当 Converter 处于空闲状态时长大于 idleTimeout ,Converter 自动销毁,推流停止。取值范围为 [5,86400]。如果设置值小于 5,则默认为 5;如果设置值大于 86400,则默认为 86400。默认值为 300。 |
rtmpUrl | String(必填) | CDN 推流地址。必须为有效的 RTMP 地址,且长度在 1024 个字符以内。 |
jitterBufferSizeMs | Int(可选) | 音频接收端到网络抖动缓冲端的网络延迟 (ms)。默认值为 1000,取值范围 [0, 1000]。jitterBufferSizeMs 设置为 0。 |
不转码推流
不转码推流的请求包体为 JSON Object 类型的 converter
字段,字段结构如图所示:
字段含义详见下表:
字段 | 类型 | 描述 |
---|---|---|
name | String(可选) | Converter 的名字。长度必须在 64 个字符以内,支持的字符集范围为: 同一时间,一个项目下不允许出现重名的 Converter,否则在尝试创建同名的 Converter 时会收到响应状态码 409(Conflict) 。name 字段管理指定项目下的 Converter。 |
rawOptions | JSON Object(必填) | Converter 的推流配置。 |
rawOptions.rtcChannel | String(必填) | 声网频道名称。即 Converter 处理的流所属的频道。字符串长度必须在 64 字节以内,支持以下字符集(共 89 个字符): |
rawOptions.rtcStreamUid | Number(必填) | 要推送的音视频流所属用户的 UID。 |
rtmpUrl | String(必填) | CDN 推流地址。必须为有效的 RTMP 地址,且长度在 1024 个字符以内。 如果你从 OBS 推流更换为旁路推流,需要按照 {Server}/{Stream Key} 的规则来拼接 RTMP URL。 |
idleTimeout | Number(可选) | Converter 处于空闲状态的最大时长(秒)。空闲指 Converter 处理的音视频流所对应的所有用户均已离开频道。当 Converter 处于空闲状态时长大于 idleTimeout ,Converter 自动销毁,推流停止。取值范围为 [5,86400]。如果设置值小于 5,则默认为 5;如果设置值大于 86400,则默认为 86400。默认值为 300。 |
jitterBufferSizeMs | Int(可选) | 音频接收端到网络抖动缓冲端的网络延迟 (ms)。默认值为 1000,取值范围 [0, 1000]。jitterBufferSizeMs 设置为 0。 |
所有可能的响应状态码详见状态码汇总表。
X-Request-ID
:UUID(通用唯一识别码),标识本次请求。该值为本次请求 header 中 X-Request-ID
。如果请求出错,请在日志中打印出该值,排查问题。
如果本次请求的响应状态码不是 2XX,那么响应 header 中可能无该字段。
X-Resource-ID
:UUID(通用唯一识别码),标识本次请求创建的 Converter 的 ID。
如果状态码为 2XX,则请求成功。响应包体中包含字段结构如图所示:
字段含义详见下表:
字段 | 类型 | 描述 |
---|---|---|
converter.id | String | Converter 的 ID。它是声网服务器生成的一个 UUID(通用唯一识别码),标识一个已创建的 Converter。 |
converter.createTs | Number | 创建 Converter 时的 Unix 时间戳(秒)。 |
converter.updateTs | Number | 最近一次更新 Converter 配置时的 Unix 时间戳(秒)。 |
converter.state | String | Converter 的运行状态:connecting : 正在连接声网推流服务器和 CDN 服务器。running : 正在进行推流。failed : 推流失败。 |
fields | String | JSON 编码方式的字段掩码,详见谷歌 protobuf FieldMask 文档。用于描述返回的 converter 中包含的字段集合。在本示例中,fields 指定了声网服务器返回 converter 字段中的 id ,createTs ,updateTs 和 state 字段子集。 |
如果状态码不为 2XX,则请求失败。包体中包含 String 类型的 message
字段,描述失败的具体原因。
{
"message": "Invalid authentication credentials."
}
该示例展示将 show68
频道内指定的两个用户使用自定义布局进行合图后推到 CDN,将频道指定的两个用户音频进行混音,且分别指定两个用户的音量大小:
{
"converter": {
"name": "show68_vertical",
"transcodeOptions": {
"rtcChannel": "show68",
"audioOptions": {
"codecProfile": "HE-AAC",
"sampleRate": 48000,
"bitrate": 128,
"audioChannels": 1,
"rtcStreamUids": [
201,
202
],
"volumes": [
{
"volume": 50,
"rtcStreamUid": 201
},
{
"volume": 150,
"rtcStreamUid": 202
}
]
},
"videoOptions": {
"canvas": {
"width": 360,
"height": 640,
"color": 0
},
"layout": [
{
"rtcStreamUid": 201,
"region": {
"xPos": 0,
"yPos": 0,
"zIndex": 1,
"width": 360,
"height": 320
},
"fillMode": "fill",
"placeholderImageUrl": "http://example.agora.io/host_placeholder.jpg"
},
{
"rtcStreamUid": 202,
"region": {
"xPos": 0,
"yPos": 320,
"zIndex": 1,
"width": 360,
"height": 320
}
},
{
"imageUrl": "http://example.agora.io/watchmark.jpg",
"region": {
"xPos": 0,
"yPos": 0,
"zIndex": 2,
"width": 36,
"height": 64
},
"fillMode": "fit"
}
],
"codec": "H.264",
"codecProfile": "high",
"frameRate": 15,
"gop": 30,
"bitrate": 400,
"seiOptions": {
"source": {
"metadata": true,
"datastream": true,
"customized": {
"payload": "example"
}
},
"sink": {
"type": 100
}
}
}
},
"rtmpUrl": "rtmp://example/live/show68",
"idleTimeout": 300
}
}
该示例展示将 show68
频道内指定的两个用户使用垂直布局进行合图后推到 CDN,并且将频道内指定的两个用户的音频进行混音:
{
"converter": {
"name": "show68_vertical",
"transcodeOptions": {
"rtcChannel": "show68",
"audioOptions": {
"codecProfile": "HE-AAC",
"sampleRate": 48000,
"bitrate": 128,
"audioChannels": 1,
"rtcStreamUids": [
201,
202
]
},
"videoOptions": {
"canvas": {
"width": 360,
"height": 640,
"color": 0
},
"layout": [
{
"rtcStreamUid": 201,
"region": {
"xPos": 0,
"yPos": 0,
"zIndex": 1,
"width": 360,
"height": 640
},
"fillMode": "fill",
"placeholderImageUrl": "http://example/host_placeholder.jpg"
},
{
"rtcStreamUid": 202,
"region": {
"xPos": 0,
"yPos": 320,
"zIndex": 1,
"width": 360,
"height": 320
}
}
],
"codec": "H.264",
"codecProfile": "high",
"frameRate": 15,
"gop": 30,
"bitrate": 400,
"layoutType": 1,
"vertical": {
"maxResolutionUid": 201,
"fillMode": "fill",
"refreshIntervalSec": 4
},
"defaultPlaceholderImageUrl": "http://example/host_placeholder.jpg",
"seiOptions": {
"source": {
"metadata": true,
"datastream": true,
"customized": {
"payload": "example"
}
},
"sink": {
"type": 100
}
}
}
},
"rtmpUrl": "rtmp://example/live/show68",
"idleTimeout": 300
}
}
该示例展示将 show68
频道内指定用户的音视频流推送到 CDN。
{
"converter": {
"name": "show68_vertical",
"rawOptions": {
"rtcChannel": "show68",
"rtcStreamUid": 201
},
"rtmpUrl": "rtmp://example/live/global"
}
}
如果状态码为 2XX,则请求成功。示例如下:
{
"converter": {
"id": "4c014467d647bb87b60b719f6fa57686",
"createTs": 1591786766,
"updateTs": 1591786766,
"state": "connecting"
},
"fields": "id,createTs,updateTs,state"
}
DELETE https://api.sd-rtn.com/{region}/v1/projects/{appId}/rtmp-converters/{converterId}
appId
: String 型必填参数。声网为每个开发者提供的 App ID。在声网控制台创建一个项目后即可得到一个 App ID。一个 App ID 是一个项目的唯一标识。converterId
: String 型必填参数。Converter 的 ID。region
: String 型必填参数。Converter 所在的区域,必须与创建 Converter 设置的 region
一致。Authorization
: 该字段的值需参考认证说明。
X-Request-ID
: UUID(通用唯一识别码),标识本次请求。声网服务器会自动生成一个 UUID,并在响应 header 中返回 X-Request-ID
字段。
声网推荐你对
X-Request-ID
赋值,声网服务器会在响应 header 中返回一个X-Custom-Request-ID
字段,以用于问题排查。
所有可能的响应状态码详见状态码汇总表。
X-Request-ID
:UUID(通用唯一识别码),标识本次请求。该值为本次请求 header 中 X-Request-ID
。如果请求出错,请在日志中打印出该值,排查问题。
如果本次请求的响应状态码不是 2XX,那么响应 header 中可能无该字段。
X-Resource-ID
:UUID(通用唯一识别码),标识本次请求删除的 Converter 的 ID。
message
字段,描述失败的具体原因。PATCH https://api.sd-rtn.com/{region}/v1/projects/{appId}/rtmp-converters/{converterId}
appId
: String 型必填参数。声网为每个开发者提供的 App ID。在声网控制台创建一个项目后即可得到一个 App ID。一个 App ID 是一个项目的唯一标识。converterId
: String 型必填参数。Converter 的 ID。region
: String 型必填参数。Converter
所在的区域,必须与创建 Converter 设置的 region 一致。sequence
:Number 型必填参数。Update 请求的序列号。取值需要大于或等于 0。请确保后一次 Update 请求的序列号大于前一次 Update 请求的序列号。序列号可以确保声网服务器按照你指定的最新配置来更新 Converter。
声网推荐你在第一次调用 Update 时,将
sequence
填0
。在第二次调用 Update 时,将sequence
填1
。在第三次调用 Update 时,将sequence
填2
。依次类推。声网服务器会按照最新 Update 请求(即最大的序列号)更新 Converter。
PATCH https://api.sd-rtn.com/{region}/v1/projects/{appId}/rtmp-converters/{converterId}?sequence={sequence}
Content-Type
: application/json
Authorization
: 该字段的值需参考认证说明。
X-Request-ID
: UUID(通用唯一识别码),标识本次请求。声网服务器会自动生成一个 UUID,并在响应 header 中返回 X-Request-ID
字段。
声网推荐你对
X-Request-ID
赋值,声网服务器会在响应 header 中返回一个X-Custom-Request-ID
字段,以用于问题排查。
你可以同时更新多个字段,字段含义详见 Create 请求 body。
Update
方法不支持更新 Converter 的如下配置:
name
idleTimeOut
transcodeOptions.rtcChannel
transcodeOptions.audioOptions.codecProfile
transcodeOptions.audioOptions.sampleRate
transcodeOptions.audioOptions.bitrate
transcodeOptions.audioOptions.audioChannels
transcodeOptions.videoOptions.codec
transcodeOptions.videoOptions.codecProfile
Create
方法创建一个只输出纯视频/音频流的 Converter 后,你无法通过 Update
方法将其更新为只输出纯音频/视频流的 Converter。layoutType
为 1
)时,仅支持更新 rtmpUrl
字段。所有可能的响应状态码详见状态码汇总表。
X-Request-ID
:UUID(通用唯一识别码),标识本次请求。该值为本次请求 header 中 X-Request-ID
。如果请求出错,请在日志中打印出该值,排查问题。
如果本次请求的响应状态码不是 2XX,那么响应 header 中可能无该字段。
X-Resource-ID
:UUID(通用唯一识别码),标识本次请求更新的 Converter 的 ID。
如果状态码为 2XX,则请求成功。响应包体中包含字段结构如图所示:
字段含义详见下表:
字段 | 类型 | 描述 |
---|---|---|
converter.id | String | Converter 的 ID。它是声网服务器生成的一个 UUID(通用唯一识别码),标识一个已创建的 Converter。 |
converter.createTs | Number | 创建 Converter 时的 Unix 时间戳(秒)。 |
converter.updateTs | Number | 最近一次更新 Converter 配置时的 Unix 时间戳(秒)。 |
converter.state | String | Converter 的运行状态:connecting : 正在连接声网推流服务器和 CDN 服务器。running : 正在进行推流。failed : 推流失败。 |
fields | String | JSON 编码方式的字段掩码,详见谷歌 protobuf FieldMask 文档。用于描述返回的 converter 中包含的字段集合。在本示例中,fields 指定了声网服务器返回 converter 字段中的 id ,createTs ,updateTs 和 state 字段子集。 |
如果状态码不为 2XX,请求失败。Body 中包含 String 类型的 message
字段,描述失败的具体原因。
更新 transcodeOptions.videoOptions.canvas
和 converter.transcodeOptions.videoOptions.layout
的示例代码如下:
{
"converter": {
"transcodeOptions": {
"videoOptions": {
"canvas": {
"width": 360,
"height": 640,
"color": 0
},
"layout": [
{
"rtcStreamUid": 201,
"region": {
"xPos": 0,
"yPos": 0,
"zIndex": 1,
"width": 360,
"height": 320
},
"fillMode": "fill",
"placeholderImageUrl": "http://example/host_placeholder.jpg"
}
]
}
}
},
"fields": "transcodeOptions.videoOptions.canvas,transcodeOptions.videoOptions.layout"
}
{
"converter": {
"transcodeOptions": {
"audioOptions": {
"volumes": [
{
"volume": 50,
"rtcStreamUid": 201
},
{
"volume": 150,
"rtcStreamUid": 201
}
]
}
}
},
"fields": "transcodeOptions.audioOptions.volumes"
}
重置指定用户的音量大小,将其设为默认值:
{
"converter": {
"transcodeOptions": {
"audioOptions": {
# 或不设置 volumes
"volumes": null
}
}
},
"fields": "transcodeOptions.audioOptions.volumes"
}
如果状态码为 2XX,则请求成功。示例代码如下:
{
"converter": {
"id": "4c014467d647bb87b60b719f6fa57686",
"createTs": 1591786766,
"updateTs": 1591788746,
"state": "running"
},
"fields": "id,createTs,updateTs,state"
}
GET https://api.sd-rtn.com/{region}/v1/projects/{appId}/rtmp-converters/{converterId}
appId
: String 型必填参数。声网为每个开发者提供的 App ID。在声网控制台创建一个项目后即可得到一个 App ID。一个 App ID 是一个项目的唯一标识。converterId
: String 型必填参数。Converter 的 ID。region
: String 型必填参数。Converter
所在的区域,必须与创建 Converter 设置的 region 一致。Content-Type
: application/json
Authorization
: 该字段的值需参考认证说明。
X-Request-ID
: UUID(通用唯一识别码),标识本次请求。声网服务器会自动生成一个 UUID,并在响应 header 中返回 X-Request-ID
字段。
声网推荐你对
X-Request-ID
赋值,声网服务器会在响应 header 中返回一个X-Custom-Request-ID
字段,以用于问题排查。
所有可能的响应状态码详见状态码汇总表。
X-Request-ID
:UUID(通用唯一识别码),标识本次请求。该值为本次请求 header 中 X-Request-ID
。如果请求出错,请在日志中打印出该值,排查问题。
如果本次请求的响应状态码不是 2XX,那么响应 header 中可能无该字段。
X-Resource-ID
:UUID(通用唯一识别码),标识本次请求更新的 Converter 的 ID。
转码推流
如果状态码为 2XX,则请求成功。转码推流响应包体中包含字段结构如图所示:
字段含义详见下表:
字段 | 类型 | 描述 |
---|---|---|
name | String | Converter 的名字。 |
transcodeOptions | JSON Object | Converter 的转码配置。 |
transcodeOptions.rtcChannel | String | 声网频道名称。 |
transcodeOptions.audioOptions | JSON Object | Converter 的音频转码配置。详见 audioOptions。 |
transcodeOptions.videoOptions | JSON Object | Converter 的视频转码配置。 |
transcodeOptions.videoOptions.canvas | JSON Object | 视频画布。详见 canvas。 |
transcodeOptions.videoOptions.layout | JSON Array | 画布上视频画面的内容描述。支持 RtcStreamView 和 ImageView 两种元素: |
transcodeOptions.videoOptions.layoutType | Number | 输出视频的画面布局类型:0 或(默认)空:自定义布局,即通过 transcodeOptions.videoOptions.layout 设置布局信息。1 :垂直布局。指定一个用户在屏幕左侧显示大视窗画面,其他用户以小视窗画面在屏幕右侧垂直排列,详见设置垂直布局。 |
transcodeOptions.videoOptions.vertical | JSON Object | 垂直布局的画面设置信息。当 layoutType 为 1 时该参数必定存在。详见 vertical。 |
transcodeOptions.videoOptions. defaultPlaceholderImageUrl |
String | 默认的用户画面背景图 URL 地址。支持 JPG、PNG 和 GIF 格式的图片。当频道内用户停止发布视频流: |
transcodeOptions.videoOptions.bitrate | Number | 输出视频的编码码率 (Kbps)。 |
transcodeOptions.videoOptions.frameRate | Number | 输出视频的编码帧率 (fps)。 |
transcodeOptions.videoOptions. codec |
String | 输出视频的编解码规格。支持如下值:H.264 (默认值)H.265 |
transcodeOptions.videoOptions. codecProfile |
String | 输出视频的编码规格。支持如下值:high (默认值): High 级别的视频编码规格,一般用于广播及视频碟片存储,高清电视。baseline : Baseline 级别的视频编码规格,一般用于低阶或需要额外容错的应用,比如视频通话、手机视频等。main : Main 级别的视频编码规格,一般用于主流消费类电子产品,如 mp4、便携的视频播放器、PSP 和 iPad 等。 如果 codec 设置为 H.265 ,则 codecProfile 默认且必须为 main 。 |
transcodeOptions.videoOptions.seiOptions | String | 输出视频中携带的用户 SEI 信息。用于向 CDN 发送用户自定义的 SEI 信息。详见 seiOptions。 |
rtmpUrl | String | CDN 推流地址。 |
idleTimeout | Number | Converter 处于空闲状态的最大时长(秒)。空闲指 Converter 处理的音视频流所对应的所有用户均已离开频道。当 Converter 处于空闲状态时长大于 idleTimeout ,Converter 自动销毁,推流停止。 |
createTs | Number | 创建 Converter 时的 Unix 时间戳(秒)。 |
updateTs | Number | 最近一次更新 Converter 配置时的 Unix 时间戳(秒)。 |
state | String | Converter 的运行状态:connecting : 正在连接声网推流服务器和 CDN 服务器。running : 正在进行推流。failed : 推流失败。 |
如果状态码不为 2XX,请求失败。Body 中包含 String 类型的 reason
字段,描述失败的具体原因。示例如下:
{
"reason": "Resource is not found and destroyed."
}
不转码推流
如果状态码为 2XX,请求成功。不转码推流响应包体中包含字段结构如图所示:
字段含义详见下表:
字段 | 类型 | 描述 |
---|---|---|
name | String | Converter 的名字。 |
rawOptions | JSON Object | Converter 的推流配置。 |
rawOptions.rtcChannel | String | 声网频道名称。即 Converter 处理的流所属的频道。 |
rawOptions.rtcStreamUid | Number | 要推送的音视频流所属用户的 UID。 |
rtmpUrl | String | CDN 推流的地址。 |
idleTimeout | Number | Converter 处于空闲状态的最大时长(秒)。空闲指 Converter 处理的音视频流所对应的所有用户均已离开频道。当 Converter 处于空闲状态时长大于 idleTimeout ,Converter 自动销毁,推流停止。 |
如果状态码不为 2XX,请求失败。Body 中包含 String 类型的 reason
字段,描述失败的具体原因。示例如下:
{
"reason": "Resource is not found and destroyed."
}
如果状态码为 2XX,请求成功。示例代码如下:
{
"name": "show68_vertical",
"transcodeOptions": {
"rtcChannel": "show68",
"audioOptions": {
"codecProfile": "HE-AAC",
"sampleRate": 48000,
"bitrate": 128,
"audioChannels": 1,
"rtcStreamUids": [
201
]
},
"videoOptions": {
"canvas": {
"width": 360,
"height": 640,
"color": 0
},
"layout": [
{
"rtcStreamUid": 201,
"region": {
"xPos": 0,
"yPos": 0,
"zIndex": 1,
"width": 360,
"height": 320
},
"fillMode": "fill",
"placeholderImageUrl": "http://example.agora.io/host_placeholder.jpg"
},
{
"rtcStreamUid": 202,
"region": {
"xPos": 0,
"yPos": 320,
"zIndex": 1,
"width": 360,
"height": 320
}
},
{
"imageUrl": "http://example.agora.io/watchmark.jpg",
"region": {
"xPos": 0,
"yPos": 0,
"zIndex": 2,
"width": 36,
"height": 64
},
"fillMode": "fit"
}
],
"codec": "H.264",
"codecProfile": "High",
"frameRate": 15,
"gop": 30,
"bitrate": 400,
"seiOptions": {}
}
},
"rtmpUrl": "rtmp://example.agora.io/live/show68",
"idleTimeout": 300,
"createTs": 1616946970,
"updateTs": 1783656785,
"state": "running"
}
{
"name": "show68_vertical",
"transcodeOptions": {
"rtcChannel": "show68",
"audioOptions": {
"codecProfile": "HE-AAC",
"sampleRate": 48000,
"bitrate": 128,
"audioChannels": 1,
"rtcStreamUids": [
201
]
},
"videoOptions": {
"canvas": {
"width": 360,
"height": 640,
"color": 0
},
"layout": [
{
"rtcStreamUid": 201,
"region": {
"xPos": 0,
"yPos": 0,
"zIndex": 1,
"width": 360,
"height": 640
},
"fillMode": "fill",
"placeholderImageUrl": "http://example.agora.io/host_placeholder.jpg"
}
],
"codec": "H.264",
"codecProfile": "high",
"frameRate": 15,
"gop": 30,
"bitrate": 400,
"layoutType": 1,
"vertical": {
"maxResolutionUid": 201,
"fillMode": "fill",
"refreshIntervalSec": 4
},
"defaultPlaceholderImageUrl": "http://example.agora.io/host_placeholder.jpg",
"seiOptions": {
"source": {
"metadata": true,
"datastream": true,
"customized": {
"payload": "example"
}
},
"sink": {
"type": 100
}
}
}
},
"rtmpUrl": "rtmp://example.agora.io/live/show68",
"idleTimeout": 300
}
{
"converter": {
"name": "wX8210Ce1VWVyGVHyaHA0W",
"rawOptions": {
"rtcChannel": "example",
"rtcStreamUid": XXXX
},
"rtmpUrl": "rtmp://vid-218.push.chinanetcenter.broadcastapp.agora.io/live/global",
"idleTimeout": 120
}
}
GET https://api.sd-rtn.com/v1/projects/{appId}/rtmp-converters
GET https://api.sd-rtn.com/v1/projects/{appId}/channels/{cname}/rtmp-converters
appId
: String 型必填参数。声网为每个开发者提供的 App ID。在声网控制台创建一个项目后即可得到一个 App ID。一个 App ID 是一个项目的唯一标识。cname
:String 型必填参数。声网频道名称。即 Converter 处理的流所属的频道。字符串长度必须在 64 字节以内,支持以下字符集(共 89 个字符):cursor
:Number 型参数。游标,用于分页查询 Converter 信息列表。取值必须大于或等于 0。
- 首次发起查询请求时无需设置
cursor
,请求成功后返回第一页 Converter 列表。- 每次查询最多返回 500 个 Converter 的相关信息,如果项目下 Converter 数量超过 500,从响应 body 中获取
cursor
,并在下一次请求的 URL 中传入该cursor
,直到响应 body 中cursor
字段值为 0,则表示已查询到项目下或指定频道的所有 Converter。
使用 Query Parameters 的 HTTP URL 如下:
GET https://api.sd-rtn.com/v1/projects/{appId}/rtmp-converters?cursor={cursor}
GET https://api.sd-rtn.com/v1/projects/{appId}/channels/{cname}/rtmp-converters?cursor={cursor}
Content-Type
: application/json
Authorization
: 该字段的值需参考认证说明。
X-Request-ID
: UUID(通用唯一识别码),标识本次请求。声网服务器会自动生成一个 UUID,并在响应 header 中返回 X-Request-ID
字段。
声网推荐你对
X-Request-ID
赋值,声网服务器会在响应 header 中返回一个X-Custom-Request-ID
字段,以用于问题排查。
所有可能的响应状态码详见状态码汇总表。
X-Request-ID
:UUID(通用唯一识别码),标识本次请求。该值为本次请求 header 中 X-Request-ID
。如果请求出错,请在日志中打印出该值,排查问题。
如果本次请求的响应状态码不是 2XX,那么响应 header 中可能无该字段。
如果状态码为 2XX,则请求成功。响应包体中包含字段结构如图所示:
字段含义详见下表:
字段 | 类型 | 描述 |
---|---|---|
success |
Bool | 请求成功。 |
data |
JSON Object | 返回数据详情。 |
data.total_count |
String | 所查项目或频道下所有 Converter 的数量。 |
data.cursor |
JSON | 游标,用于分页查询 Converter 信息列表。cursor 为 0 表示已查询到项目下或指定频道的所有 Converter;否则需要继续查询。 |
data.members.rtcChannel |
String | 声网频道名称。即 Converter 处理的流所属的频道。 |
data.members.converterName |
String | Converter 名称。 |
data.members.updateTs |
Number | 最近一次更新 Converter 配置时的 Unix 时间戳(秒)。 |
data.members.appId |
String | 声网为每个开发者提供的 App ID。在声网控制台创建一个项目后即可得到一个 App ID。一个 App ID 是一个项目的唯一标识。 |
data.members.rtmpUrl |
String | CDN 推流地址。 |
data.members.converterId |
String | Converter 的 ID。Converter 的唯一标识。 |
data.members.create |
Number | 创建 Converter 时的 Unix 时间戳(秒)。 |
data.members.idleTimeout |
Number | Converter 处于空闲状态的最大时长(秒)。空闲指 Converter 处理的音视频流所对应的所有用户均已离开频道。当 Converter 处于空闲状态时长大于 idleTimeout ,Converter 自动销毁,推流停止。 |
data.members.state |
String | Converter 的运行状态:connecting : 正在连接声网推流服务器和 CDN 服务器。running : 正在进行推流。failed : 推流失败。 |
如果状态码为 2XX,则请求成功。示例代码如下:
{
"success": true,
"data": {
"total_count": 1,
"cursor": 0,
"members": [
{
"rtcChannel": "testchannel",
"status": "200",
"converterName": "wX821XXXXVWVyGVHyaHA0W",
"updateTs": "1641267823",
"appId": "aab8b8f5aXXXX469a63042fcfafe7063",
"rtmpUrl": "rtmp://example/live/areu",
"ip": "183.131.160.244",
"converterId": "889B6D4BXXXXB62E68CCDA978BF21350",
"create": "1641267818",
"idleTimeout": "120",
"state": "running"
}
]
}
}
本节总结使用推流 RESTful API 的基础注意事项:
X-Request-ID
和 X-Resource-ID
字段值,以方便排查问题。name
参数,详见 name
参数解释。region
设置为 CDN 源站所在区域,详见 region
参数解释。Delete
该 Converter,再重新创建一个 Converter。Update
时,sequence
值递增,详见 sequence
参数解释。如需了解更多集成建议,请参考旁路推流集成最佳实践。
本节介绍旁路推流 RESTful API 的相关数据类型定义。
Converter 的音频转码配置。
字段 | 类型 | 描述 |
---|---|---|
codecProfile |
String(可选) | Converter 输出的音频编解码器。支持如下值:LC-AAC (默认值): MPEG-4 AAC LC。HE-AAC : High-Efficiency AAC。 |
sampleRate |
Number(可选) | Converter 输出的音频编码采样率 (Hz),可填 32000 ,44100 或 48000 (默认值)。 |
bitrate |
Number(可选) | Converter 输出的音频编码码率 (Kbps)取值范围为 [32,128]。默认值为 48。如果音频编解码器为 LC-AAC,推荐音频编码码率取值范围为 [32, 112]。如果音频编解码器为 HE-AAC,推荐音频编码码率取值范围为 [40, 96]。 |
audioChannels |
Number(可选) | Converter 输出的音频声道数,可填 1 (默认值) 或 2 。 |
rtcStreamUids |
JSON Array(可选) | 参与混音的用户 UID 数组。 |
volumes |
JSON Array(可选) | 设置参与混音的用户音量。rtcStreamUids )时该字段生效。Update 方法调整指定用户的音量,每一次 Update 请求成功会将本次指定用户以外的其他用户的音量恢复为默认值 100 。 |
volumes.rtcStreamUid |
Number | 待设置音量的混音用户 UID。volumes.rtcStreamUid 需要存在于rtcStreamUids 数组中,否则请求失败,响应状态码为 400 。 |
volumes.volume |
Number | 指定的混音用户的音量。默认值为 100 ,取值范围 [0, 200]。 |
Converter 的视频转码配置。
videoOptions.canvas
视频画布配置。
字段 | 类型 | 描述 |
---|---|---|
width |
Number(必填) | 画布的宽度 (pixel)。取值范围为 [66,1920]。 |
height |
Number(必填) | 画布的高度 (pixel)。取值范围为 [66,1920]。 |
color |
Number(可选) | 画布的背景色。RGB 颜色值,以十进制数表示。如 255 代表蓝色。取值范围为 [0,16777215]。默认值为 0,即黑色。 |
videoOptions.layout
画布上视频画面的内容描述。
videoOptions.layout.RtcStreamView
用于配置画布上各用户的视频画面。
字段 | 类型 | 描述 |
---|---|---|
rtcStreamUid |
Number(必填) | 视频流所属用户的 UID。 |
region |
JSON Object(必填) | 用户视频画面在画布上的显示区域。超出画布的视频画面会被裁剪,无法显示。 |
region.xPos |
Number(必填) | 画面在画布上的 x 坐标 (pixel)。以画布左上角为原点,x 坐标为画面左上角相对于原点的横向位移。 |
region.yPos |
Number(必填) | 画面在画布上的 y 坐标 (pixel)。以画布左上角为原点,y 坐标为画面左上角相对于原点的纵向位移。 |
region.zIndex |
Number(必填) | 画面的图层编号。取值范围为 [0,100]。0 代表最下层的图层。100 代表最上层的图层。 |
region.width |
Number(必填) | 画面的宽度 (pixel)。 |
region.height |
Number(必填) | 画面的高度 (pixel)。 |
fillMode |
String(可选) | 画面的显示方式。fill :在保持长宽比的前提下,缩放画面,使画面充满容器。fit :在保持长宽比的前提下,缩放画面,使得画面在容器内完整显示出来。 |
placeholderImageUrl |
String(可选) | 用户画面的背景图 URL 地址。支持 JPG、PNG 和 GIF 格式的图片。当频道内用户停止发布视频流,如果设置了该字段,用户的视频画面将切换为该背景图,否则会显示为画布背景色。 |
videoOptions.layout.ImageView
配置画布上的视频图片,可用于当水印。
字段 | 类型 | 描述 |
---|---|---|
imageUrl |
String(必填) | 图片的 HTTP(S) URL。支持 JPG 和 PNG 格式的图片。 |
region |
JSON Object(必填) | 图片在画布上的显示区域。超出画布的图片会被裁剪,无法显示。 |
region.xPos |
Number(必填) | 图片在画布上的 x 坐标 (pixel)。以画布左上角为原点,x 坐标为图片左上角相对于原点的横向位移。 |
region.yPos |
Number(必填) | 图片在画布上的 y 坐标 (pixel)。以画布左上角为原点,y 坐标为图片左上角相对于原点的纵向位移。 |
region.zIndex |
Number(必填) | 图片的图层编号。取值范围为 [0,100]。0 代表最下层的图层。100 代表最上层的图层。 |
region.width |
Number(必填) | 图片的宽度 (pixel)。 |
region.height |
Number(必填) | 图片的高度 (pixel)。 |
fillMode (可选) |
String | 图片的显示方式。fill :在保持长宽比的前提下,缩放图片,使图片充满容器。fit :在保持长宽比的前提下,缩放图片,使得图片在容器内完整显示出来。 |
videoOptions.vertical
配置垂直布局的视频画面。
字段 | 类型 | 描述 |
---|---|---|
maxResolutionUid |
(可选)Number | 显示大视窗画面的用户 UID。如果未设置 maxResolutionUid ,则布局刷新时音量最大的用户显示为大视窗画面。maxResolutionUid 可能会导致画面布局每隔 3 秒变化一次,如果需要布局稳定不变,请设置该参数。 |
fillMode |
(可选)String | 用户画面的显示方式。fill :在保持长宽比的前提下,缩放画面,使画面充满容器。fit :在保持长宽比的前提下,缩放画面,使得画面在容器内完整显示出来。 |
videoOptions.seiOptions
设置输出视频中携带的用户 SEI 信息。
字段 | 类型 | 描述 |
---|---|---|
source |
JSON Object(可选) | 设置 SEI 信息的数据来源。默认为空。 |
source.metadata |
Bool(可选) | 设置是否传入 metadata 类型的 SEI 信息。 |
source.datastream |
Bool(可选) | 设置是否传入声网 DataStream 类型的 SEI 信息 。true :传入声网 DataStream 类型的 SEI 信息。false :不传入声网 DataStream 类型的 SEI 信息。 |
source.customized |
JSON Object(可选) | 自定义 SEI 信息。该 SEI 信息会被转换为声网 SEI 规范的 SEI 信息。默认为空。 |
source.customized.prefixForAgoraSei |
String(可选) | 设置 SEI 信息的 payload 前缀。长度必须在 32 个字符以内,默认为空。 |
source.customized.payload |
String(可选) | 设置 SEI 信息的 payload。长度必须在 4096 个字符以内,默认为空。SEI 信息被转换为声网 SEI 规范的 SEI 信息时,该 payload 会被传入到 SEI 的 app_data 中。 |
sink |
JSON Object(可选) | 设置输出 SEI 信息的属性。默认为空。 |
sink.type |
Int(可选) | 设置输出 SEI 信息的 payload type。默认为 100。 |
声网服务器限制用户 API 调用速率,超出限制速率时会返回状态码 429(Too Many Requests)
。如果你有更高调用速率需求,请联系技术支持。
API | 限流说明 |
---|---|
Create |
一个项目中,创建 Converter 的速率上限为 50 次/秒。 |
Delete |
一个项目中,销毁 Converter 的速率上限为 50 次/秒。 |
Update |
一个项目中,更新一个指定的 Converter 的速率上限为 50 次/秒。 |
Get |
一个项目中,获取一个指定的 Converter 推流状态的速率上限为 50 次/秒。 |
message
或 reason
字段内容排查问题。响应 Body 中具体字段可参考每个 API 请求响应的文档。状态码 | 可能的 message 或 reason 字段内容 |
---|---|
200 OK | / |
400 Bad Request | |
401 Unauthorized | Invalid authentication credentials. |
403 Forbidden | No valid permission to use this function. Contact us. |
404 Not Found | Resource is not found and destroyed. |
409 Conflict | Resource with the same name has already existed. Use the existing resource, otherwise delete it and create a new resource. |
429 Too Many Requests | |
500 Unknown | Internal errors. Contact us for troubleshooting. |
501 Not Implemented | The method requested has not been implemented. |
503 Service Unavailable | |
504 Gateway Timeout | Gateway timeout. Check whether the resource is created, if not, re-create a new resource. |
设置转码输出媒体流的视频分辨率、帧率和码率时,声网推荐你使用默认值。你也可以参考下表设值。如果设置的码率超出合理范围,声网服务器会在合理区间内自动调整码率。
分辨率 | 帧率 (fps) | 码率 (Kbps) |
---|---|---|
160 × 120 | 15 | 130 |
120 × 120 | 15 | 100 |
320 × 180 | 15 | 280 |
180 × 180 | 15 | 200 |
240 × 180 | 15 | 240 |
320 × 240 | 15 | 400 |
240 × 240 | 15 | 280 |
424 × 240 | 15 | 440 |
640 × 360 | 15 | 800 |
360 × 360 | 15 | 520 |
640 × 360 | 30 | 1200 |
360 × 360 | 30 | 800 |
480 × 360 | 15 | 640 |
480 × 360 | 30 | 980 |
640 × 480 | 15 | 1000 |
480 × 480 | 15 | 800 |
640 × 480 | 30 | 1500 |
480 × 480 | 30 | 1200 |
848 × 480 | 15 | 1220 |
848 × 480 | 30 | 1860 |
640 × 480 | 10 | 800 |
1280 × 720 | 15 | 2260 |
1280 × 720 | 30 | 3420 |
960 × 720 | 15 | 1820 |
960 × 720 | 30 | 2760 |