OSS支持以RTMP协议推流音视频至存储空间(Bucket),并转储为HLS协议格式,同时提供了丰富的鉴权、授权机制实现更细颗粒度的音视频数据访问控制。
前提条件
已创建了存储空间。具体操作,请参见控制台创建存储空间。
基础操作
OSS支持使用RTMP推流协议上传H264格式的视频数据和AAC格式的音频数据,并通过访问PlayURL地址的方式获取音视频数据。
上传音视频数据
调用PutLiveChannel接口创建LiveChannel。
调用该接口会返回RTMP推流地址PublishURL和播放地址PlayURL。
通过PublishURL推流音视频文件。
OSS将上传的音视频文件按HLS协议转储,即转储为一个m3u8格式的索引文件和多个ts格式的视频文件。具体操作,请参见RTMP推流上传。
获取音视频数据
您可以通过浏览器直接访问PlayURL地址的方式,即访问m3u8索引文件的方式来获取音视频数据。
Android和iOS等移动平台,以及PC端的少数浏览器例如Microsoft Edge和Safari,支持通过访问m3u8文件的方式播放视频。Chrome等浏览器需要嵌入Video.js等JavaScript脚本才能正常播放视频。
您在公共读写的Bucket中通过OSS上传和获取音视频,意味着任何人都有权限读写您的音视频数据,从而造成不必要的数据泄露和流量计费等问题。默认情况下,OSS Bucket的访问权限为私有,且拒绝任何来源的跨域请求。推荐您根据自身的使用场景,结合跨域资源共享CORS、防盗链、私有Bucket签名机制中的一种或多种方式,从而有效保护您的数据安全。
跨域资源共享CORS
如果不是通过浏览器直接访问OSS的音视频,而是先访问第三方的网页并在网页中嵌入了OSS的音视频,则很有可能遇到跨域问题,导致视频无法播放。这是因为当Web服务器和OSS不属于同一个域时,将违反同源策略,浏览器默认会拒绝该连接。
例如,Web服务器地址为http://192.168.xx.xx:8080,浏览器访问该地址获取了网页,网页的JavaScript脚本里嵌入了视频,视频来源指向OSS Bucket。此时,浏览器需要再次向OSS发送请求,试图访问OSS中的视频数据。但是,浏览器识别到OSS Bucket的访问地址与http://192.168.xx.xx:8080的网页地址不属于同一个域,则会先向OSS Bucket询问是否允许跨域请求。OSS Bucket默认不开启CORS配置,因此会拒绝浏览器的跨域请求,使得浏览器不能正常播放音视频。如下图所示:
您可以通过OSS的跨域资源共享,解决因跨域限制导致音视频无法正常播放的问题。
登录OSS管理控制台。
单击Bucket列表,之后单击目标Bucket名称。
单击 。
单击创建规则。
在创建跨域规则页面配置各项参数。
结合本文档示例场景,请将来源设置为http://192.168.xx.xx:8080,其他参数设置请参见设置跨域资源共享。
如果来源为具体的域名,请填写完整的域名,例如www.example.com,不可省略为example.com。
如果来源为精准的IP地址,请填写包括协议类型和端口号在内的完整的IP地址,例如http://xx.xx.xx.xx:80,不可省略为xx.xx.xx.xx。
浏览器对跨域配置通常会有数十秒至几分钟的缓存时间。如果希望跨域配置立即生效,建议清空浏览器缓存后刷新网页。
防盗链
CORS规则可以有效阻止其他网站服务器在网页中嵌入您的音视频资源。但如果您通过直接访问OSS Bucket的方式获取音视频,则CORS规则将失效。在这种情况下,您可以通过OSS防盗链对Bucket设置Referer白名单的机制,避免其他人盗取您的音视频资源。
默认情况下,Bucket允许空Referer,通过本地浏览器访问PlayURL的方式可以直接观看视频。为了防止音视频资源被其他人盗用,您可以将Bucket设置为不允许空Referer,并将您信任的域名或IP加入Referer白名单。此时,除Referer白名单以外的第三方访问音视频资源时均会被拒绝,并返回403 Forbidden错误。
登录OSS管理控制台。
单击Bucket列表,之后单击目标Bucket名称。
在左侧导航栏,选择数据安全>防盗链。
在防盗链页面,打开防盗链开关。
在Referer框中,填写域名或IP地址,例如*.aliyun.com。
您可以结合实际使用场景设置不同的Referer字段。Referer配置示例详情请参见设置防盗链。
在空Referer框中,选择不允许空Referer。
说明选择不允许空Referer且设置了Referer白名单,则只有HTTP或HTTPS header中包含Referer字段的请求才能访问OSS资源。
选择不允许空Referer但未设置Referer白名单,效果等同于允许空Referer,即防盗链设置无效。
单击保存。
私有Bucket签名机制
为了保护您的数据安全,OSS默认Bucket的读写权限为私有。因此当您需要向私有Bucket执行读取或写入操作时,需要使用签名机制向OSS声明您的操作权限。
当您向私有Bucket推流时,需要对推流地址进行签名后才能上传音视频文件。具体操作,请参见RTMP推流地址及签名。
使用Python SDK获取签名的推流地址示例如下:
示例返回值为字符串形式格式如下:
rtmp://xxx.oss-cn-beijing.aliyuncs.com/live/xxx?playlistName=xxx&OSSAccessKeyId=xxx&Expires=xxx&Signature=xxx
最后Signature的值为签名,前面的为视频流的相关信息。
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
# 填写Bucket名称,例如examplebucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# 创建并配置流频道。
# 该索引文件包含3个ts文件,每个ts文件的时长为5秒。此示例中的5秒时长为建议值,具体时长取决于关键帧。
channel_name = "your_channel_name"
playlist_name = "your_playlist_name.m3u8"
frag_count_config = 3
frag_duration_config = 5
create_result = bucket.create_live_channel(
channel_name,
oss2.models.LiveChannelInfo(
status = 'enabled',
description = 'your description here',
target = oss2.models.LiveChannelInfoTarget(
playlist_name = playlist_name,
frag_count = frag_count_config,
frag_duration = frag_duration_config)))
# 获取RTMP推流签名地址。
# 示例中的expires是一个相对时间,表示从现在开始此次推流过期的秒数。
# 获取签名后的signed_url后即可使用推流工具直接进行推流。一旦连接上OSS,即使超出设置的expires也不会断流,OSS仅在每次推流连接时检查expires是否合法。
signed_rtmp_url = bucket.sign_rtmp_url(channel_name, playlist_name, expires=3600)
print(signed_rtmp_url)
OSS访问私有Bucket中的文件时,需要在URL中加上签名。HLS的访问机制为动态访问m3u8索引文件,根据索引文件的内容多次请求下载最新的ts文件,此过程中的每一次请求都需要在URL中加上签名。
为此,OSS对音视频数据的访问提供了动态签名机制,即只需在首次访问m3u8文件时在URL中添加x-oss-process=hls/sign
, OSS将对返回的播放列表中的所有ts地址自动按照与m3u8完全相同的方式进行签名。
使用Python SDK动态签名机制访问音视频的示例如下:
# 获取观流的动态签名地址。
your_object_name = "test_rtmp_live/test.m3u8"
style = "hls/sign"
# 生成签名URL时,OSS默认会对Object完整路径中的正斜线(/)进行转义,从而导致生成的签名URL无法直接使用。
# 设置slash_safe为True,OSS不会对Object完整路径中的正斜线(/)进行转义,此时生成的签名URL可以直接使用。
signed_download_url = bucket.sign_url('GET', your_object_name, 3600, params={'x-oss-process': style}, slash_safe=True)
print(signed_download_url)