实时音视频服务端开发指南

    服务器录制开发指南

    录制架构

    为满足客户个性化的存储及处理性能的需要,服务器录制方案采用客户自备 Linux 录制服务器,部署录制服务程序的方案进行实现。如图:

    image

    主要功能

    融云音视频服务器端录制服务,通过简单的操作方法,帮助开发者快速、灵活地部署录制服务,以此来实现一对一、一对多的音视频通话或直播的录制。

    概念说明:

    • mix 模式为混流录制模式,将房间内所有用户的音视频通话录制成一个文件
    • simple 模式为分流录制模式,将房间内的每个用户的音频、视频流分别录制成一个文件
    主要功能 功能描述
    全终端支持 支持 Android SDK、iOS SDK 和 Web SDK 的音视频录制
    多应用录制 支持同时对多个应用(AppKey)进行音视频录制。
    自动全录 以默认方式,从通话开始至通话结束全程录制。
    simple 模式录制 支持房间内每个用户的音视频分别录制。以两人会议为例:
    1.均为音视频,则录制会生成 4 个文件(2 纯音频+2 纯视频)。
    2.均为音频,则录制会生成 2 个纯音频文件。
    3.一方为音视频,另一方为纯音频,则录制会生成 3 个文件(2个纯音频 + 1 个纯视频)。
    注意:暂时不支持选择指定用户进行音视频录制。
    mix 模式录制 支持房间内所有用户的音视频混合录制。以两人会议为例:
    1.均为音视频,则录制会生成 1 个音视频文件。
    2.均为音频,则录制会生成 1 个音频文件。
    3.一方为音视频,另一方为纯音频,则录制会生成 1 个音视频文件。
    注意:暂时不支持选择指定用户进行音视频录制。
    纯音频录制(simple 模式) 支持房间内每个用户的音视频中只录制音频,不录制视频。例如:一个两人会议会生成 2 个纯音频文件。
    纯音频录制(mix 模式) 支持房间内所有的音视频中只录制音频,不录制视频。并且,将音频混合成一个文件。例如:一个两人会议会生成 1 个纯音频文件,不录制视频。
    纯视频录制(simple 模式) 支持房间内每个用户的音视频中只录制视频,不录制音频。例如:一个两人会议会生成 2 个纯视频文件。
    纯视频录制(mix 模式) 支持房间内所有的音视频中只录制视频,不录制音频。并且,将视频混合成一个文件。例如:一个两人会议会生成 1 个纯视频文件,不录制音频。
    支持多文件类型 支持录制 mkv、mp4、flv 视频文件类型。

    录制模式

    • mix 模式:(全录,仅录视频,仅录音频)

      整个会议录制成一个文件

      文件夹名称:时间戳_channelId

      视频文件:channelId.mkv / channelId.mp4 / channelId.flv

      音频文件:channelId.aac

    • simple 模式:(全录,仅录视频,仅录音频)

      每道媒体流生成一个文件。(一个二人会议会生成 4 个文件,2 纯音频+2 纯视频)

      文件夹名称:时间戳_channelId

      视频文件:channelId用户id.mkv / channelId用户id.mp4 / channelId_用户id.flv

      音频文件:channelId用户id.aac / channelId用户id.wav

    录制过程中的文件以 .tmp 结尾,录制完成后去掉 .tmp 扩展名

    SDK 版本支持

    服务端录制程序支持的 SDK 版本信息如下:

    音视频 SDK Android 版本 iOS 版本 Web 版本
    RTCLib SDK 支持 SDK 3.0.0 及以上版本 支持 SDK 3.0.0 及以上版本 支持 SDK 3.0.0 及以上版本
    CallLib SDK 支持 SDK 2.9.13 及以上版本 支持 SDK 2.9.13 及以上版本 支持 SDK 3.1.0 及以上版本
    CallKit SDK 支持 SDK 2.9.13 及以上版本 支持 SDK 2.9.13 及以上版本 不提供 CallKit SDK

    前期准备

    开通房间状态同步

    实现服务端录制必须开通音视频房间状态同步功能,此功能用于向第三方同步音视频会话的房间状态信息。

    音视频房间状态同步功能是指在音视频通话过程中,房间的创建、销毁、人员的进出房间、音视频资源发布/取消等状态变更,会以 HTTP 请求方式发送到第三方的 Server,开发者可根据状态,决定是否进行录制。

    音视频房间状态同步功能,开通方式:

    开发者后台音视频服务中,开通服务端录像功能后,即可使用此功能,申请时需要提供房间状态同步自备录制服务器的地址,融云会将房间内所有信息都同步给这个地址,开通 2 小时后生效。

    注:如集群部署需要提交 nginx 负载地址

    自备录制服务器

    自备 Linux 录制服务器环境要求如下:

    系统
    • Docker 自动部署(推荐使用,受外部环境影响较小)

      • Linux kernel 大于 3.10 版本
    • Native 自动部署/ Native 手动部署(特殊情况下使用)

      • SUSE Linux Enterprise Server 11 sp3 及以上
      • Ubuntu 16.04 及以上
      • CentOS 7.4 及以上
    网络

    服务器需要开通一个公网出访和入访 tcp 端口,用于房间状态同步:

    带宽
    • 根据录制的媒体流数量和分辨率决定。

      例如:一个 640×480 视频媒体流需要的带宽为 500kbps,每个二人会议两个媒体流,50 个二人会议 100 个视频流则需要 50mbps 带宽。

    硬件配置
    • 每个二人会议的内存消耗约为 100M
    • 10 分钟视频文件大小为 30M,音频文件为 5M
    • 主要瓶颈在于 CPU,处理器 i7 4790(4 核 8 线程) 同时能支持的会话数量如下:
    音视频通话 mix 模式 simple 模式
    2 人分辨率为 640×480,帧率 15,单路码流 500kbps 支持 8 个会话 支持 10 个会话

    Demo 版本说明

    目前服务端录制功能已更新到 3.0.10 版本,更新内容:

    1. 支持录制多个应用

    2. 房间模型优化,根据 Session 创建房间。

    3. 增加日志等级配置

    4. 修改配置,可以录制 mkv/mp4/flv 文件

    5. 日志中可以显示丢包率

    6. 编码优化,CPU 占用率降低 60%

    录制 Demo 说明

    融云提供了服务端录制 Demo,包括两部分程序:

    1. 房间状态同步消息处理程序

      此程序实现了对接收音视频房间状态同步消息的处理,如用户加入、退出房间、发布音视频流、取消发布音视频流,在收到状态信息后,处理自身录制业务逻辑。

      注:融云提供此功能的开源项目,如果需要进行二次开发,收到状态同步后实现其他业务逻辑,详细参考音视频状态同步服务

    2. 底层录制服务程序

      此程序实现了房间中音视频录制的处理逻辑,需要开发者在状态同步服务中加入录制的相关配置。

    录制流程

    image

    图解:

    1. 用户加入指定房间,开始发布音视频信息
    2. 融云 MediaServer 服务器判断客户是否开通音视频录制功能
    3. 已开通音视频录制功能,则向客户自备的 Linux 录制服务器进行音视频房间状态同步,如未开通则不进行房间状态同步,无法录制
    4. 客户自备的 Linux 录制服务器,接收音视频通话的房间状态信息
    5. 房间状态同步消息处理程序,决定是否进行录制,融云提供的录制 Demo 中包括此处理程序,默认为录制
    6. 进行自动录制
    7. 向融云 MediaServer 服务器,订阅需要录制的音视频流
    8. 底层录制服务程序接收订阅的音视频数据,开始录制

    单机部署说明

    服务端录制 Demo 支持 Docker 自动部署(推荐使用), Native 自动部署、Native 手动部署三种方式。使用融云录制 Demo 不做任何二次开发的情况下推荐使用 Docker 部署。

    Docker 自动部署

    1. 安装或准备 docker 环境。

    2. 命令行执行以下内容。

    docker run -d  --rm \
    --ulimit core=0 \
    --name recording \
    --env APPKEY="{your-appkey}" \
    --env SECRET="{your-secret}" \
    --env RECORD_MODE={your-record-mode} \
    --env VIDEO_FORMAT={file-type} \
    -p {your-tcp-port}:80 \
    -v {your-record-dir}:/data/record \
    -v {your-log-dir}:/var/log/supervisor \
    rongcloud/demo-rtc-record:latest
    

    录制视频类型支持 3 种格式 mkv、mp4、flv,通过 VIDEO_FORMAT 进行设置,例如:

    docker run -d  --rm \
    --ulimit core=0 \
    --name recording \
    --env APPKEY="XXXXXXXXX" \
    --env SECRET="YYYYYYYYY" \
    --env RECORD_MODE=3 \
    --env VIDEO_FORMAT="mkv" \
    -p {port}:80 \
    -v /data/record/files:/data/record \
    -v /data/record/logs:/var/log/supervisor \
    rongcloud/demo-rtc-record:latest
    

    其中,需要确保自备录制服务器已经开通 your-tcp-port 对应的 tcp 端口,用于接收房间状态同步消息。

    相关项目:

    Native 自动部署

    通过命令脚本一键自动化部署录制程序。下载部署程序 v3.0.10

    部署步骤说明:

    1. 修改 global.conf 配置,说明如下:

      #房间状态同步服务端口配置,默认8800
      channel_port=8800
      
      #录制程序服务 HTTP 端口配置,默认 5000
      record_port=5000
      
      #需要录制的 appKey
      #必填
      #在融云官网开发者后台创建应用获取 http://www.rongcloud.cn/
      appKey=
      
      #必填
      #在融云官网开发者后台创建应用获取 http://www.rongcloud.cn/ appKey 和 secret 会用来校验签名
      secret=
      
      #录制模式 1:自动全录模式(默认);
      recordType=1
      
      #录像保存地址,不配置则不会启动录像
      recordSaveDir=/data/record/
      
      #mediaserver 地址(以下为公有云默认地址,私有云客户请联系商务获取)
      mediaUrl=https://rtc-info.ronghub.com
      
      #录制模式,默认 mix 全录模式 3:
      #simlpe 模式(全录 0,仅录视频 1,仅录音频 2)
      #mix 模式(全录 3,仅录视频 4,仅录音频 5)
      Publish_mode=3
      
      #视频格式: mkv/mp4/flv
      VideoFormat=mkv
      
      #音频格式: aac/wav
      AudioFormat=aac
      
      #大小流 high:1  low:2 
      SimulCast=1
      
    2. 下载部署程序 v3.0.10后运行 install.sh 文件完成部署

    Native 手动部署

    需要对以下两个程序分别进行部署:

    • 房间状态同步消息处理程序,为 GitHub 开源项目(demo-rtc-server-record)立即下载

    • 底层录制服务程序(RongRTC-Record),未进行开源,开箱即用,立即下载 v3.0.10

    房间状态同步消息处理程序,打包部署流程如下:

    1. 基于源码 Maven 打包构建

      1)下载或克隆 demo-rtc-server-record 项目

      2)进入项目 demo-rtc-server-record 目录

      3)安装依赖 mvn install

      4)打包 mvn clean package

    2. 创建 Demo 运行目录,并进入该目录,将 maven 打包好的可执行 jar 包 demo-rtc-server-record-*.jar 复制到当前目录

    3. 将项目源码根目录中的 ServiceSettings.properties,log4j.properties 复制到当前目录

    4. 修改状态同步服务的配置文件 ServiceSettings.properties 详细如下:

      #必填,服务监听的 http 端口
      port=8800
      
      #必填,应用的 appKey 在融云开发者后台创建应用后获取 http://www.rongcloud.cn
      appKey=
      
      #必填,在融云开发者后台创建应用后获取 http://www.rongcloud.cn,appkey 和 secret 会用来校验签名
      secret=
      
      #底层录制服务程序,录制节点地址,根据部署情况修改 IP、端口即可
      recordNodeAddr=http://127.0.0.1:5000/record
      
      #录像保存地址,不配置则不会启动录像
      recordSaveDir=/data/record/
      
      #录制模式 1:自动全录模式(默认);
      recordType=1
      
    5. 启动程序

      nohup java -jar demo-rtc-server-record-*.jar &

    6. 验证,观察日志 nohup.out,无报错,当有房间状态变更时能收到请求。

    底层录制服务程序(RongRTC-Record)部署步骤如下:

    1. 程序部署

      centos 系统:以 root 身份执行 centos-record_install.sh

      ubantu 系统:以 root 身份执行 ubuntu-record_install.sh

    2. 将依赖库 libs 的路径添加到 /data/libs/(用户可以自定义目录)

      cp -drf libs /data/libs

    3. 将 bin 目录下的所有文件放到指定目录地址 /data/services/record/,执行 cp bin/* /data/services/record/

      将 export LD_LIBRARY_PATH=/data/libs/ /data/services/record//Recorder --port 5000 放到 supervisor

      备注:HTTP 默认端口 5000 此端口应该和录制程序中的 ServiceSettings.properties 配置保持一致

    4. 更新配置文件 ServiceSettings.properties 说明如下:

    #录制程序服务 HTTP 端口配置,默认 5000
    port=5000
    
    #必填,需要录制的 appKey 在融云开发者后台创建应用后获取 http://www.rongcloud.cn/
    appKey=
    
    #音视频服务地址(以下为公有云默认地址,私有云客户请联系商务获取)
    mediaUrl=https://rtc-info.ronghub.com
    
    #录制模式: simlpe 模式(全录,仅录视频,仅录音频),mix 模式(全录,仅录视频,仅录音频),默认 mix 全录模式
    
    #SIMPLE=0, SIMPLE_VIDEO=1,SIMPLE_AUDIO=2, MIX = 3, MIX_VIDEO = 4, MIX_AUDIO = 5
    Publish_mode=3
    
    #视频格式: mkv/mp4/flv
    VideoFormat=mkv
    
    #音频格式: aac/wav
    AudioFormat=aac
    
    #大小流 high:1  low:2 
    SimulCast=1
    

    集群部署说明

    如果是集群部署,需要安装 nginx,参考下面的脚本对 HTTP 请求进行路由(原理是:根据 http request 中 ChannelID 头进行路由),将改好的脚本放在 nginx 启动加载配置的目录中即可。

    upstream cluster {
        hash $http_ChannelId consistent;
        #对应的录制节点的 IP、端口
        server 172.19.21.174:7788;
        server 172.19.21.175:7788;
    }
    
    server {
        listen 8800;
    
        location / {
          proxy_pass http://cluster;
        }
    }
    

    状态码

    code 描述
    41002 Token 或 Member 为空,请确定客户端是否发布资源
    50010 HTTP 请求超时
    50011 HTTP 响应错误,MediaServer URL 错误
    50012 HTTP 请求错误,含网络不可达,请求未能为能正常发出

    音视频状态同步服务

    向客户服务端同步音视频通话的房间状态信息。包括:音视频通话过程中的房间创建、销毁、用户加入房间、用户退出房间、发布音视频资源。

    开通方式

    开发者后台音视频服务中,开通服务端录像功能后,即可使用此功能,申请时需要提供房间状态同步自备录制服务器的地址,融云会将房间内所有信息都同步给这个地址,开通 2 小时后生效。注:对音视频状态同步消息的处理。可以参考 Demo 快速集成。

    注:如集群部署需要提交 nginx 负载地址

    HTTP 方法:POST

    JSON 示例:

    {
        "appKey":"XXXXXXX",
        "channelId":"xxxx",
        "event":1,
        "userId":"xxxx",
        "timestamp":2222222,
        "token":"xxxx",
        "extra":"xxxx",
        "members":
               [{
                    "userId": "userid1",
                    "data":{
                        "key1":"value1"
                     }
               },
               {
                    "userId": "userid2",
                    "data":{
                        "key2":"value2"
                    }
               }]
    }
    

    表单参数:

    名称 类型 说明
    appKey String 应用 AppKey,开发者后台创建应用后获取
    channelId String 房间号,频道唯一标识
    event Int 事件:1 同步房间信息、2 房间创建、3 房间销毁、11 成员加入、12 成员退出、20 资源发生变动(发布资源或者取消发布资源)。
    userId String 当前事件的用户 Id
    timestamp Long 当前事件发生的时间戳
    token String userId 所获取的 Token 用来订阅资源时验证请求合法性
    extra String 备用字段
    members Array 用户信息,只有在同步房间信息时,members 里的 member 列表才是全量的,其他事件都是对应事件中的 user 信息,比如 user1 资源发布,那 members 里的信息只有 user1 的资源信息

    members 结构说明:

    名称 类型 说明
    userId String 用户 ID
    data JSON 用户房间数据,key、value 均为 String 存储,这块定义了资源的标识信息。具体的定义见下面的标示。

    members 中 data 定义了资源的标示,格式如下:

    {
        "data":
           {
              "uris":
                 [
                    {
                       "tag":"XXX",
                       "msid":"XXX", 
                       "mediaType":0, 
                       "state":1, 
                       "uri":"XXX" 
                    },
                    {
                       "tag":"XXX",
                       "msid":"XXX", 
                       "mediaType":1, 
                       "state":1, 
                       "uri":"XXX"
                    }
                 ]
           } 
    }
    

    uris 为当前 user 资源集合,JSON 中结构说明如下:

    参数名称 类型 说明
    uris Array 资源集,当前 user 的资源集合
    tag String 备用字段
    msid String msid 资源 ID
    mediaType Int 资源类型,0 音频,1 视频
    state Int 资源 track 状态,0 关闭,1 开启
    uri String 资源详细信息