阿里云直播转录播,视频保存到oss(附上完整代码)

AddLiveAppRecordConfig

官方:调用AddLiveAppRecordConfig配置APP录制,输出内容保存到OSS中
视频直播的录制功能可以将直播数据录制成 HLS 协议文件

自己理解的意思就是:配置要直播转录播的模板,当阿里那边检测到有此配置的appname和StreamName在推流时,进行录制保存至oss,简称配置录播,直播录制存储到oss
配置好的模板可以在阿里云的控制台,点击直播管理 -> 录制文件管理 -> 管理录制配置 -> 存储至oss,看到配置的模板,录制好的文件同样可以在 录制文件管理 -> 存储至oss里面搜索到

拓展
HLS(HTTP Live Streaming) 把整个流分成一个个小的基于 HTTP 的文件来下载,每次只下载一些。HLS 协议由三部分组成:HTTP、M3U8、TS。这三部分中,HTTP 是传输协议,M3U8 是索引文件,TS 是音视频的媒体信息,每一个 .m3u8 文件,分别对应若干个 ts 文件,这些 ts 文件才是真正存放视频的数据,m3u8 文件只是存放了一些 ts 文件的配置信息和相关路径


# AddLiveAppRecordConfig  

def add_live_app_record_config(self, cdn_domain, app_name, oss_bucket, prefix, record_format='m3u8'):
        """
        配置APP录制,输出内容保存到OSS中
        注意:修改配置后,新配置对修改之前的直播流不生效,必须重新推流才能生效!这就意味着当点击开始直播时必须先断流再推流,才能实现录播的配置
             如何实现先断流再推流,这需要再次调用两个接口,请继续往下看
        @params: cdn_domain 推流加速域名
        @params: app_name 创建推流时候二级
        @params: oss_bucket oss存储bucket名称
        @params: prefix oss存储的录制文件名前缀
        @return :
        {
            "RequestId": "16A96B9A-F203-4EC5-8E43-CB92E68F4CD8", 
        }
        """
        action = "AddLiveAppRecordConfig"
        request, querystring = self.get_stream_request(action, cdn_domain, app_name)
        querystring['OssEndpoint'] = settings.ALIYUN_OSS_ENDPOINT
        querystring['OssBucket'] = oss_bucket
        querystring['RecordFormat.1.Format'] = record_format
        querystring['RecordFormat.1.OssObjectPrefix'] = prefix + "/{AppName}/{StreamName}_{Sequence}_{StartTime}_{EndTime}"
        querystring[
            'RecordFormat.1.SliceOssObjectPrefix'] = prefix + "/{Date}/{AppName}/{StreamName}/{UnixTimestamp}_{Sequence}"
        querystring['RecordFormat.n.CycleDuration'] = 60 * 60 * 5 # 每段最长录制5小时

        response = request.request("GET", self.api_domain, params=querystring)
        return response

注意官方文档这三个请求参数

  1. RecordFormat.N.Format
  2. RecordFormat.N.OssObjectPrefix 定义的是推流结束180秒后生成的.m3u8索引文件
  3. RecordFormat.N.SliceOssObjectPrefix 定义的是实际存储视屏的ts文件

在自己编写请求参数的时候,需要把里面的大写N变为整数,比如1,对应的就是{Sequence}参数,也就是说顺序,从1开始递增

# 这个参数也比较特殊,写成这样
querystring['RecordFormat.n.CycleDuration'] = 60 * 60 * 5   # 表示每段最长录制5小时

CreateLiveStreamRecordIndexFiles

在给直播配置了录播功能后,视频直播录制在直播过程中会生成 TS 文件,但是仅在推流结束 180 秒后才会生成 m3u8 索引文件,无法在直播过程中生成,并且该索引文件时间为推流开始到结束,用户无法根据业务需要自定义索引范围。因此,视频直播提供录制索引管理功能供用户对录制索引 m3u8 文件的管理功能。这就是CreateLiveStreamRecordIndexFiles

官方:该API用于创建某个时间范围的M3U8索引文件

理解:把某个已经配置好录播并且已经推流过的文件,通过此API生成M3U8索引文件,创建m3u8文件只能选择最近3个月的录制内容,并且是已经录制好的保存到oss中的文件,调用成功后,返回的数据中有一个是RecordUrl字段,这就是索引文件所在的地址,它就可以通过播放器进行播放

def create_live_stream_record_index_files(self, cdn_domain, app_name, stream_name, oss_endpoint, oss_bucket
        , oss_object, start_time, end_time):
        """
        根据开始,结束时间创建录制索引文件
        @params: cdn_domain 推流加速域名
        @params: app_name 创建推流时候二级
        @params: stream_name 三级
        @params: oss_endpoint settings中ALIYUN_OSS_ENDPOINT
        @params: oss_bucket settings中ALIYUN_OSS_BUCKET
        @params: oss_object oss存储具体位置以及文件名
        @params: start_time 开始时间戳
        @params: end_time 结束时间戳
        @return:
            {
              "RecordIndexInfoList": {
                "RecordIndexInfo": [
                  {
                    "OssBucket": "bucket",
                    "OssEndpoint": "oss-cn-hangzhou.aliyuncs.com",
                    "OssObject": "atestObject.m3u8",
                    "RecordId": "c4d7f0a4-b506-43f9-8de3-07732c3f3d82",
                    "DomainName": "xxx",
                    "AppName": "xxx",
                    "StreamName": "xxx",
                    "Duration": 588.849,
                    "Height": 480,
                    "Width": 640,
                    "StartTime": "2016-05-25T05:37:11Z",
                    "EndTime": "2016-05-25T05:47:11Z",
                    "CreateTime": "2016-05-27T09:40:56Z",
                    "RecordUrl": "http://xxx.xxx/atestObject.m3u8"
                  }
                ]
              },
              "RequestId": "DE24625C-7C0F-4020-8448-9C31A50C1556"
            }
        """
        action = "CreateLiveStreamRecordIndexFiles"

        request, querystring = self.get_stream_request(action, cdn_domain, app_name, stream_name)
        querystring['OssEndpoint'] = oss_endpoint
        querystring['OssBucket'] = oss_bucket
        querystring['OssObject'] = oss_object
        querystring["StartTime"] = start_time
        querystring["EndTime"] = end_time

        response = request.request("GET", self.api_domain, params=querystring)
        return response

AddLiveAppRecordConfig 接口放置在开始直播的点击事件上,让直播一开始就配置上录播的功能,而CreateLiveStreamRecordIndexFiles接口放置在结束直播的点击事件上,结束直播生成.m3u8的索引文件,入库即可
通过上面的两个接口就可以把直播的内容同时存储到oss中了,会生成ts文件和.m3u8文件,取.m3u8文件即可

以上两个接口都会生成.m3u8索引文件,有啥区别呢?用哪个呢?
看图
在这里插入图片描述
图片中出现的情况都是在没有调用CreateLiveStreamRecordIndexFiles接口,仅在调用AddLiveAppRecordConfig 接口情况下出现的,图片中两条对应的都是RecordFormat.N.SliceOssObjectPrefix字段,但是很明显第一次是默认格式,只有在以后的索引文件中才会带上顺序和开始结束时间

在看图
在这里插入图片描述
如图所示,当调用过AddLiveAppRecordConfig 接口,然后调用CreateLiveStreamRecordIndexFiles接口后,就会生生成新的.m3u8文件,并且将原来已有的文件进行合并,但是不会删除间隔时间段的索引文件

上面说到的:修改配置后,新配置对修改之前的直播流不生效,必须重新推流才能生效!这就意味着当点击开始直播时必须先断流再推流,才能实现录播的配置又需要两个接口来实现:ForbidLiveStream和ResumeLiveStream

ForbidLiveStream

ResumeLiveStream

官方:调用ForbidLiveStream禁止某条流的推送,可以预设某个时刻将流恢复。
官方:调用ResumeLiveStream恢复某条流的推送。

def forbidden_or_resume_pulish_stream(self, cdn_domain, app_name, stream_name, forbi_resume="forbidden"):
        """
        禁止/恢复推流
        rtmp://center_domain/app_name/stream_name/
        @params: cdn_domain 推流加速域名
        @params: app_name 创建推流时候二级
        @params: stream_name 三级
        @params: forbi_resume 禁止(forbidden)/恢复(resume)
        """
        action_dict = {
            "forbidden": "ForbidLiveStream",
            "resume": "ResumeLiveStream"
        }
        action = action_dict.get(forbi_resume)
        if not action:
            raise

        request, querystring = self.get_stream_request(action, cdn_domain, app_name, stream_name)
        querystring["AppName"] = app_name
        querystring["StreamName"] = stream_name
        querystring["LiveStreamType"] = "publisher"

        response = request.request("GET", self.api_domain, params=querystring)
        return response

阿里云签名代码:
上面所有用到的request.request(“GET”, self.api_domain, params=querystring) 之类的,用的都是下面的AliyunRequestCDN类的request方法

class AliyunRequestCDN(Request):
    def __init__(self, version):
        self.version = version

    def request(self, method, url, **kwargs):
        if isinstance(kwargs.get("data", ""), dict):
            body = _json.dumps(kwargs["data"], ensure_ascii=False)
            body = body.encode('utf8')
            kwargs["data"] = body

        params = kwargs.get("params")
        if not params:
            params = {}
        # 公共参数
        params["Format"] = "JSON"
        params["Version"] = self.version
        params["AccessKeyId"] = settings.ALIYUN_ACCESS_KEY
        params["SignatureMethod"] = "HMAC-SHA1"
        params["Timestamp"] = utc_nowtime()
        params["SignatureVersion"] = "1.0"
        params["SignatureNonce"] = nowtime()

        # 代签名字符串
        sign_string = get_signature_string(params)
        # 签名字符串
        signature = aliyun_sgin(settings.ALIYUN_SECRET, sign_string)
        params["Signature"] = signature

        kwargs['params'] = params

        logger.info("aliyun request :{}".format(params))

        r = requests.request(
            method=method,
            url=url,
            verify=False,
            **kwargs
        )
        logger.info("aliyun request url: {}".format(r.url))
        json = r.json()
        logger.info('aliyun request json info: {}'.format(json))
        return json

其实现在完全不需要自己构造签名,只需要跟着阿里的调试机制,会自动生成带签名的代码

总结
配置录播的接口被调用后,会在oss中生成ts文件来存储视屏,当停止推流180秒后,会生成.m3u8的索引文件,当调用创建索引的接口后,会立即生成.m3u8的索引文件,那样的话就不会生成在推流180秒后,生成.m3u8的索引文件了。因为一个就够用了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值