本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 CloudFront 串流影片
媒體工作流程通常會將隨需影片 (VOD) 檔案、HTTP 即時串流 (HLS) 套件、映像和圖形,存放在編輯器、生產者和自動化系統使用 NFS 或 SMB 寫入 的 ONTAP 磁碟區的 FSx 上。
透過將 Amazon S3 存取點連接至 FSx for ONTAP 磁碟區,CloudFront 可以直接從磁碟區提供內容。編輯器和生產系統一律以 NFS 或 SMB 的方式發佈至磁碟區,CloudFront 會透過存取點擷取內容,檢視器會從最近的 CloudFront 節點接收內容。
在本教學課程中,您將範例影片編碼為 HLS 適應性位元速率套件、將輸出上傳至連接至 FSx for ONTAP 磁碟區的存取點、使用原始存取控制設定 CloudFront 分佈,讓檢視器無法繞過 CloudFront 直接到達磁碟區,並確認串流播放端對端。
注意
本教學課程大約需要 40 到 60 分鐘才能完成。 AWS 服務 使用的 會針對您建立的資源產生費用。如果您立即完成所有步驟,包括清除區段,則美國東部 (維吉尼亞北部) 的預期成本低於 1 美元。 AWS 區域此預估不包含 FSx for ONTAP 磁碟區本身的持續費用。
模式的運作方式
請求流程為:
檢視器的播放器 (瀏覽器、行動應用程式、智慧型電視) 會從 CloudFront 網域請求 HLS 主播放清單。
CloudFront 會檢查其邊緣快取。錯過時,CloudFront 會使用 Signature 第 4 版 (SigV4) 搭配其原始存取控制 (OAC) 簽署請求,並將其轉送至存取點的 Amazon S3 端點。
存取點會針對其存取政策授權請求,允許 CloudFront 服務主體範圍限定於您的分佈,並從 FSx 傳回 ONTAP 磁碟區的請求物件。
CloudFront 會在邊緣快取回應,並將其傳回給檢視器。
HLS 套件會混合兩種可從不同快取政策中受益的檔案類型:
播放清單 (
.m3u8) 說明哪些區段組成串流。使用短Cache-ControlTTL,讓您可以快速發佈更新的播放清單。區段 (
.ts) 包含編碼的視訊和音訊。一旦寫入,區段的內容永遠不會變更,因此請使用不可變的長Cache-ControlTTL。
先決條件
步驟 1:將來源視訊編碼為 HLS 套件
使用 FFmpeg 以 360p、720p 和 1080p 產生具有逼真的over-the-top(OTT) 位元速率的三變式 HLS 套件。產生的套件包含一個主播放清單,參考每個變數的播放清單,每個播放清單都列出四秒的傳輸串流區段。
-
下載來源影片。
$mkdir -p ~/media && cd ~/media curl -sSL -o sintel-1080p.mp4 \ https://download.blender.org/durian/trailer/sintel_trailer-1080p.mp4 -
使用三種適應性位元速率變體將影片編碼至 HLS。
$mkdir hls && cd hls ffmpeg -i ../sintel-1080p.mp4 \ -filter_complex "[0:v]split=3[v1][v2][v3]; \ [v1]scale=w=640:h=360[v1out]; \ [v2]scale=w=1280:h=720[v2out]; \ [v3]scale=w=1920:h=1080[v3out]" \ -map "[v1out]" -c:v:0 libx264 -b:v:0 800k -maxrate:v:0 856k -bufsize:v:0 1200k \ -map "[v2out]" -c:v:1 libx264 -b:v:1 3000k -maxrate:v:1 3200k -bufsize:v:1 4500k \ -map "[v3out]" -c:v:2 libx264 -b:v:2 5500k -maxrate:v:2 5900k -bufsize:v:2 8250k \ -preset veryfast -g 48 -keyint_min 48 -sc_threshold 0 \ -map a:0 -map a:0 -map a:0 -c:a aac -b:a:0 96k -b:a:1 128k -b:a:2 128k \ -f hls -hls_time 4 -hls_playlist_type vod -hls_flags independent_segments \ -hls_segment_filename "stream_%v/seg_%03d.ts" \ -master_pl_name master.m3u8 \ -var_stream_map "v:0,a:0,name:360p v:1,a:1,name:720p v:2,a:2,name:1080p" \ "stream_%v/playlist.m3u8"命令會產生目錄樹狀目錄,其中包含一個主播放清單、三個變體播放清單,以及每個變體的傳輸串流區段。
hls/ ├── master.m3u8 ├── stream_360p/ │ ├── playlist.m3u8 │ ├── seg_000.ts │ └── ... ├── stream_720p/ │ ├── playlist.m3u8 │ ├── seg_000.ts │ └── ... └── stream_1080p/ ├── playlist.m3u8 ├── seg_000.ts └── ...
步驟 2:將 HLS 套件上傳至存取點
上傳套件兩次:使用短 TTL 的播放清單一次,使用長不可變 TTL 的區段一次。正確設定Content-Type很重要:大多數玩家需要 application/vnd.apple.mpegurl .m3u8和 video/mp2t .ts。
將access-point-alias取代為您的存取點別名。
$# Playlists: short TTL, m3u8 content type aws s3 cp ~/media/hls/ "s3://access-point-alias/content/sintel/" \ --recursive --exclude "*" --include "*.m3u8" \ --content-type "application/vnd.apple.mpegurl" \ --cache-control "max-age=60" # Segments: long immutable TTL, ts content type aws s3 cp ~/media/hls/ "s3://access-point-alias/content/sintel/" \ --recursive --exclude "*" --include "*.ts" \ --content-type "video/mp2t" \ --cache-control "max-age=31536000,immutable"
驗證使用預期的內容類型和快取標頭上傳的兩個檔案。
$aws s3api head-object --bucketaccess-point-alias\ --key content/sintel/master.m3u8 \ --query '{ContentType:ContentType,CacheControl:CacheControl}'
步驟 3:建立原始存取控制
原始存取控制 (OAC) 可讓 CloudFront 向您的存取點簽署請求,因此只有 CloudFront 可以擷取物件。如果沒有 OAC,檢視器可以透過直接從存取點端點請求物件來繞過 CloudFront。
$aws cloudfront create-origin-access-control \ --origin-access-control-config \ 'Name=fsxn-media-oac,SigningProtocol=sigv4,SigningBehavior=always,OriginAccessControlOriginType=s3'
記下回應中的 Id。在下一個步驟中用得到。
步驟 4:建立 CloudFront 分佈
使用存取點別名做為原始網域來建立 CloudFront 分佈。使用 CachingOptimized受管快取政策,該政策會遵守您在步驟 2 中設定的Cache-Control標頭。
-
將下列組態儲存至名為 的檔案
dist.json,取代預留位置。{ "CallerReference": "fsxn-media-1", "Comment": "FSx for ONTAP media delivery", "Enabled": true, "DefaultRootObject": "", "Origins": { "Quantity": 1, "Items": [{ "Id": "fsxn-ap", "DomainName": "access-point-alias.s3.region.amazonaws.com", "S3OriginConfig": {"OriginAccessIdentity": ""}, "OriginAccessControlId": "oac-id", "ConnectionAttempts": 3, "ConnectionTimeout": 10 }] }, "DefaultCacheBehavior": { "TargetOriginId": "fsxn-ap", "ViewerProtocolPolicy": "redirect-to-https", "AllowedMethods": { "Quantity": 2, "Items": ["GET", "HEAD"], "CachedMethods": {"Quantity": 2, "Items": ["GET", "HEAD"]} }, "Compress": true, "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6" }, "PriceClass": "PriceClass_100", "ViewerCertificate": {"CloudFrontDefaultCertificate": true} }注意
PriceClass_100僅在北美洲和歐洲使用 CloudFront 節點,可降低本教學課程的成本。對於全域邊緣涵蓋範圍,請將 值變更為PriceClass_All。如需詳細資訊,請參閱選擇 CloudFront 分佈的價格分級。 -
建立分佈。
$aws cloudfront create-distribution --distribution-config file://dist.json \ --query 'Distribution.{Id:Id,DomainName:DomainName,ARN:ARN}'在回應中記下分佈 ID、ARN 和網域名稱。分佈大約需要五分鐘的時間進行部署。您可以在部署時繼續執行步驟 5。
步驟 5:連接允許 CloudFront 的存取點政策
存取點政策會授予 CloudFront 服務主體使用 AWS:SourceArn條件讀取物件的許可,範圍限定於您的特定分佈。
-
將下列政策儲存至名為 的檔案
ap-policy.json,取代預留位置。{ "Version": "2012-10-17", "Statement": [{ "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": {"Service": "cloudfront.amazonaws.com"}, "Action": "s3:GetObject", "Resource": "arn:aws:s3:region:account-id:accesspoint/access-point-name/object/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::account-id:distribution/distribution-id" } } }] } -
將政策連接至存取點。
$aws s3control put-access-point-policy \ --account-idaccount-id\ --nameaccess-point-name\ --policy file://ap-policy.json
步驟 6:驗證播放
等待分佈達到Deployed狀態。
$aws cloudfront get-distribution --iddistribution-id\ --query 'Distribution.Status'
透過 CloudFront 擷取主播放清單。
$curl -sS "https://distribution-domain/content/sintel/master.m3u8"
回應應列出三個變體。
#EXTM3U #EXT-X-VERSION:6 #EXT-X-STREAM-INF:BANDWIDTH=1031744,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2" stream_360p/playlist.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=3497301,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2" stream_720p/playlist.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=6311285,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2" stream_1080p/playlist.m3u8
檢查回應標頭是否有正確的內容類型、快取控制和快取狀態。
$curl -sSI "https://distribution-domain/content/sintel/stream_1080p/seg_000.ts"
成功的回應會顯示 content-type: video/mp2t、 cache-control: max-age=31536000,immutable和 x-cache標頭,指出回應是來自邊緣還是原始伺服器。
最後,使用 FFmpeg 端對端播放串流,以確認所有區段都正確擷取和解碼。
$ffprobe -v error \ -show_entries stream=codec_name,width,height \ -show_entries format=duration \ "https://distribution-domain/content/sintel/master.m3u8"
您也可以在 Safari 或 VLC 中開啟主播放清單 URL,或使用 JavaScript 播放器將其內嵌在網頁中,例如 hls.js。
擴展模式
搭配 HTTPS 使用自訂網域。為您的網域請求 ACM 憑證,將其連接到 分佈,然後新增指向 CloudFront 網域的 CNAME 記錄。如需說明,請參閱搭配 CloudFront 使用自訂 URLs。
使用簽章的 URLs Cookie 保護高級內容。對於需要授權的內容 (訂閱服務、早期存取預覽、地理圍欄內容),請使用 CloudFront 簽章的 URLs Cookie。請參閱使用簽章的 URLs Cookie 提供私有內容。
當您發佈新內容時,快取會失效。當您取代播放清單或上傳新的 HLS 套件時,請使用 從 CloudFront 邊緣
aws cloudfront create-invalidation移除舊版本。對於具有長 TTLs,通常不需要失效,因為每個套件的區段檔案名稱是唯一的。為以瀏覽器為基礎的玩家啟用 CORS。如果不同網域上的瀏覽器型 HLS 播放器載入串流,請使用 CloudFront 回應
Access-Control-Allow-Origin標頭政策將標頭新增至回應。記錄檢視器請求。啟用 CloudFront 標準記錄或即時日誌,以擷取檢視器對分析、計費或濫用偵測的請求。
疑難排解
- 403 從 CloudFront 禁止
存取點政策遺失、不包含 CloudFront 服務主體,或
AWS:SourceArn條件參考錯誤的分佈 ARN。使用 驗證政策,aws s3control get-access-point-policy並確認分發 ARN 符合您aws cloudfront create-distribution回應中的政策。- 播放器載入主播放清單,但無法播放
檢查區段檔案是否具有
Content-Type: video/mp2t,而播放清單是否具有Content-Type: application/vnd.apple.mpegurl。有些玩家會拒絕具有一般內容類型的客群。使用正確的--content-type旗標重新上傳。- 新的播放清單需要一些時間才能聯絡觀眾
CloudFront 會快取
Cache-Control標頭所設定 TTL 的播放清單。如果您需要較短的 TTL,請使用較小的max-age值重新上傳播放清單,或建立失效。區段沒有此問題,因為其內容不會變更。x-cache: Miss from cloudfront在每個請求上當區域中的檢視器第一次請求檔案時,這是正常的。CloudFront 會在遺漏時從原始伺服器擷取 ,並快取 TTL 的回應。從該節點對相同檔案的後續請求會傳回
Hit from cloudfront。- 直接存取存取點遭拒
這是預期的行為。OAC 需要來自 CloudFront SigV4-signed請求,且存取點政策限制對 CloudFront 服務主體的存取。檢視器只能透過分發網域存取內容。
清除
停用並刪除分佈,然後刪除剩餘的資源。必須先停用分佈,才能將其刪除,這需要幾分鐘的時間。
停用需要來自 的兩個值get-distribution-config:ETag適用於 的 --if-match,以及適用於 的內部DistributionConfig物件 --distribution-config(完整回應也包含update-distribution不接受的 ETag)。
$# Capture the current ETag and the DistributionConfig body GET_ETAG=$(aws cloudfront get-distribution-config --iddistribution-id\ --query 'ETag' --output text) aws cloudfront get-distribution-config --iddistribution-id\ --query 'DistributionConfig' --output json \ | jq '.Enabled = false' > dist-updated.json # Disable the distribution. The response returns a new ETag. UPDATE_ETAG=$(aws cloudfront update-distribution --iddistribution-id\ --if-match "$GET_ETAG" --distribution-config file://dist-updated.json \ --query 'ETag' --output text) # Wait for Status to reach Deployed before deleting. aws cloudfront get-distribution --iddistribution-id\ --query 'Distribution.Status' # Delete the distribution using the ETag from the update call. aws cloudfront delete-distribution --iddistribution-id\ --if-match "$UPDATE_ETAG" # Fetch the OAC ETag, then delete the OAC. OAC_ETAG=$(aws cloudfront get-origin-access-control --idoac-id\ --query 'ETag' --output text) aws cloudfront delete-origin-access-control --idoac-id\ --if-match "$OAC_ETAG" aws s3control delete-access-point-policy \ --account-idaccount-id--nameaccess-point-nameaws s3 rm "s3://access-point-alias/content/sintel/" --recursive