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)