View a markdown version of this page

Streaming di video utilizzando CloudFront - FSx per ONTAP

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Streaming di video utilizzando CloudFront

I flussi di lavoro multimediali generalmente archiviano i contenuti finiti, come file video on demand (VOD), pacchetti HTTP Live Streaming (HLS), immagini e grafica, su un volume FSx for ONTAP su cui editor, produttori e sistemi di automazione scrivono utilizzando NFS o SMB.

Con un access point Amazon S3 collegato al volume FSx for ONTAP, CloudFront puoi distribuire contenuti direttamente dal volume. Gli editor e i sistemi di produzione pubblicano sul volume tramite NFS o SMB come hanno sempre fatto, CloudFront recuperano i contenuti attraverso il punto di accesso e gli utenti li ricevono dalla edge location più vicina. CloudFront

In questo tutorial, codificate un video di esempio come pacchetto HLS adaptive-bitrate, caricate l'output su un punto di accesso collegato a un volume FSx for ONTAP, configurate una CloudFront distribuzione con controllo dell'accesso all'origine in modo che gli spettatori non possano bypassare per raggiungere direttamente il volume e verificare che lo streaming venga riprodotto dall'inizio CloudFront alla fine.

Nota

Il completamento di questo tutorial richiede dai 40 ai 60 minuti circa. Le risorse Servizi AWS utilizzate sono soggette a costi per le risorse create. Se completi tempestivamente tutti i passaggi, inclusa la sezione Pulizia, il costo previsto è inferiore a 1 USD negli Stati Uniti orientali (Virginia settentrionale). Regione AWS Questa stima non include i costi correnti per il volume FSx for ONTAP stesso.

Come funziona il pattern

Il flusso di richiesta è:

  • Il player di uno spettatore (browser, app mobile, smart TV) richiede la playlist principale HLS dal CloudFront dominio.

  • CloudFront ne controlla l'edge cache. In caso di errore, CloudFront firma una richiesta utilizzando Signature Version 4 (SigV4) con il relativo controllo di accesso all'origine (OAC) e la inoltra all'endpoint Amazon S3 per il punto di accesso.

  • Il punto di accesso autorizza la richiesta in base alla sua politica di accesso, che consente il CloudFront servizio principale destinato alla distribuzione, e restituisce l'oggetto richiesto dal volume FSx for ONTAP.

  • CloudFront memorizza la risposta nella cache sul bordo e la restituisce al visualizzatore.

I pacchetti HLS combinano due tipi di file che beneficiano di diverse politiche di cache:

  • Le playlist (.m3u8) descrivono i segmenti che compongono lo stream. Utilizza un breve Cache-Control TTL per pubblicare rapidamente playlist aggiornate.

  • I segmenti (.ts) contengono il video e l'audio codificati. Una volta scritto, il contenuto di un segmento non cambia mai, quindi usa un TTL lungo e immutabileCache-Control.

Prerequisiti

  • Un volume FSx for ONTAP con un access point Amazon S3 collegato. Il punto di accesso deve avere un'origine di rete Internet in modo che CloudFront possa raggiungerlo. Per istruzioni, consulta Creazione di un access point.

  • AWS CLI la versione 2 è installata e configurata con credenziali in grado di creare CloudFront distribuzioni, controlli di accesso all'origine e politiche dei punti di accesso.

  • FFmpeg installato localmente, per codificare il video di esempio in HLS.

  • Un file video sorgente. Questo tutorial utilizza il trailer di Sintel della Blender Foundation, una clip di 52 secondi a 1080p pubblicata con licenza Creative Commons.

Passaggio 1: codifica il video sorgente come pacchetto HLS

Usa FFmpeg per produrre un pacchetto HLS a tre varianti a 360p, 720p e 1080p con bitrate over-the-top (OTT) realistici. Il pacchetto risultante include una playlist principale che fa riferimento a playlist per variante, ognuna delle quali elenca segmenti di stream di trasporto di quattro secondi.

  1. Scaricate il video sorgente.

    $ mkdir -p ~/media && cd ~/media curl -sSL -o sintel-1080p.mp4 \ https://download.blender.org/durian/trailer/sintel_trailer-1080p.mp4
  2. Codifica il video in HLS con tre varianti di bitrate adattivo.

    $ 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"

    Il comando produce un albero di directory con una playlist principale, tre playlist varianti e i segmenti del flusso di trasporto per ciascuna variante.

    hls/ ├── master.m3u8 ├── stream_360p/ │ ├── playlist.m3u8 │ ├── seg_000.ts │ └── ... ├── stream_720p/ │ ├── playlist.m3u8 │ ├── seg_000.ts │ └── ... └── stream_1080p/ ├── playlist.m3u8 ├── seg_000.ts └── ...

Fase 2: Caricare il pacchetto HLS sul punto di accesso

Carica il pacchetto due volte, una volta per le playlist con un TTL breve e una volta per i segmenti con un TTL lungo e immutabile. L'impostazione corretta Content-Type è importante: la maggior parte dei giocatori richiede per e per. application/vnd.apple.mpegurl .m3u8 video/mp2t .ts

access-point-aliasSostituiscilo con l'alias del tuo punto di accesso.

$ # 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"

Verifica che entrambi i file siano stati caricati con i tipi di contenuto e le intestazioni della cache previsti.

$ aws s3api head-object --bucket access-point-alias \ --key content/sintel/master.m3u8 \ --query '{ContentType:ContentType,CacheControl:CacheControl}'

Passaggio 3: Creare un controllo di accesso all'origine

Un controllo di accesso all'origine (OAC) consente di CloudFront firmare le richieste al punto di accesso in modo che solo gli oggetti CloudFront possano essere recuperati. Senza OAC, gli utenti potrebbero aggirare il problema richiedendo gli oggetti direttamente CloudFront dall'endpoint del punto di accesso.

$ aws cloudfront create-origin-access-control \ --origin-access-control-config \ 'Name=fsxn-media-oac,SigningProtocol=sigv4,SigningBehavior=always,OriginAccessControlOriginType=s3'

Prendere nota dell'ID Id nella risposta. Verrà usato nel prossimo passaggio.

Fase 4: Creare la distribuzione CloudFront

Crea una CloudFront distribuzione con l'alias del punto di accesso come dominio di origine. Utilizza la policy della cache CachingOptimized gestita, che rispetta le Cache-Control intestazioni impostate nel passaggio 2.

  1. Salva la seguente configurazione in un file denominatodist.json, sostituendo i segnaposto.

    { "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} }
    Nota

    PriceClass_100utilizza le CloudFront edge location solo in Nord America ed Europa, il che mantiene bassi i costi per questo tutorial. Per una copertura perimetrale globale, modifica il valore inPriceClass_All. Per ulteriori informazioni, vedi Scelta della classe di prezzo per una CloudFront distribuzione.

  2. Crea la distribuzione.

    $ aws cloudfront create-distribution --distribution-config file://dist.json \ --query 'Distribution.{Id:Id,DomainName:DomainName,ARN:ARN}'

    Annota l'ID di distribuzione, l'ARN e il nome di dominio nella risposta. L'implementazione della distribuzione richiede circa cinque minuti. È possibile continuare con la Fase 5 durante la distribuzione.

Passaggio 5: Allega una politica del punto di accesso che consenta CloudFront

La policy del punto di accesso concede al CloudFront servizio l'autorizzazione principale a leggere gli oggetti, in base alla distribuzione specifica dell'utente utilizzando la AWS:SourceArn condizione.

  1. Salva la seguente politica in un file denominatoap-policy.json, sostituendo i segnaposto.

    { "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" } } }] }
  2. Allega la politica al punto di accesso.

    $ aws s3control put-access-point-policy \ --account-id account-id \ --name access-point-name \ --policy file://ap-policy.json

Fase 6: Verifica della riproduzione

Attendi che la distribuzione raggiunga Deployed lo stato.

$ aws cloudfront get-distribution --id distribution-id \ --query 'Distribution.Status'

Scarica la playlist principale. CloudFront

$ curl -sS "https://distribution-domain/content/sintel/master.m3u8"

La risposta dovrebbe elencare le tre varianti.

#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

Controlla le intestazioni di risposta per verificare il tipo di contenuto, il controllo della cache e lo stato della cache corretti.

$ curl -sSI "https://distribution-domain/content/sintel/stream_1080p/seg_000.ts"

Viene visualizzata content-type: video/mp2t una risposta corretta e un'x-cacheintestazione che indica se la risposta proviene dal bordo o dall'origine. cache-control: max-age=31536000,immutable

Infine, riproduci lo stream dall'inizio alla fine con FFmpeg per confermare che tutti i segmenti vengono recuperati e decodificati correttamente.

$ ffprobe -v error \ -show_entries stream=codec_name,width,height \ -show_entries format=duration \ "https://distribution-domain/content/sintel/master.m3u8"

Puoi anche aprire l'URL della playlist principale in Safari o VLC o incorporarla in una pagina web usando un player come hls.js. JavaScript

Estendere il pattern

  • Usa un dominio personalizzato con HTTPS. Richiedi un certificato ACM per il tuo dominio, allegalo alla distribuzione e aggiungi un record CNAME che punti al dominio. CloudFront Per istruzioni, consulta Usare URL personalizzati con. CloudFront

  • Proteggi i contenuti premium con URL firmati o cookie firmati. Per i contenuti che richiedono l'autorizzazione (servizi in abbonamento, anteprime ad accesso anticipato, contenuti georeferenziati), utilizza URL firmati o cookie firmati. CloudFront Vedi Pubblicazione di contenuti privati con URL firmati e cookie firmati.

  • Invalida la cache quando pubblichi nuovi contenuti. Quando sostituisci una playlist o carichi un nuovo pacchetto HLS, usalo aws cloudfront create-invalidation per rimuovere le vecchie versioni dai bordi. CloudFront Per i segmenti immutabili con TTL lunghi, l'invalidazione in genere non è necessaria perché i nomi dei file dei segmenti sono unici per pacchetto.

  • Abilita CORS per i lettori basati su browser. Se un lettore HLS basato su browser su un dominio diverso carica il tuo stream, aggiungi le intestazioni alle risposte utilizzando una politica sulle Access-Control-Allow-Origin intestazioni di risposta. CloudFront

  • Registra le richieste dei visualizzatori. Abilita la registrazione CloudFront standard o i log in tempo reale per acquisire le richieste degli utenti per analisi, fatturazione o rilevamento di abusi.

Risoluzione dei problemi

403 Proibito da CloudFront

La policy del punto di accesso è assente, non include il CloudFront servizio principale o la AWS:SourceArn condizione fa riferimento all'ARN di distribuzione errato. Verifica la politica con aws s3control get-access-point-policy e conferma che l'ARN di distribuzione corrisponda a quello nella tua aws cloudfront create-distribution risposta.

Il giocatore carica la playlist principale ma non riesce a suonarla

Verifica che i file di segmento abbiano Content-Type: video/mp2t e le playlist abbianoContent-Type: application/vnd.apple.mpegurl. Alcuni giocatori rifiutano i segmenti con tipi di contenuto generici. Re-upload con la bandiera corretta--content-type.

Le nuove playlist richiedono tempo per raggiungere gli spettatori

CloudFront memorizza nella cache le playlist per il TTL impostato dall'intestazione. Cache-Control Se hai bisogno di un TTL più breve, carica nuovamente la playlist con un max-age valore inferiore o crea un'invalidazione. I segmenti non presentano questo problema perché il loro contenuto non cambia.

x-cache: Miss from cloudfrontsu ogni richiesta

Questo è normale la prima volta che un visualizzatore in una regione richiede un file. CloudFront recupera dall'origine in caso di errore e memorizza nella cache la risposta per il TTL. Vengono restituite le richieste successive per lo stesso file da quella edge location. Hit from cloudfront

L'accesso diretto al punto di accesso è negato

Si tratta di un comportamento normale. L'OAC richiede SigV4-signed richieste da e CloudFront la politica del punto di accesso limita l'accesso al principale del CloudFront servizio. Gli spettatori possono accedere al contenuto solo tramite il dominio di distribuzione.

Eliminazione

Disattiva ed elimina la distribuzione, quindi elimina le risorse rimanenti. La distribuzione deve essere disabilitata prima di poter essere eliminata, operazione che richiede alcuni minuti.

La disabilitazione richiede due valoriget-distribution-config: il ETag for --if-match e l'DistributionConfigoggetto interno per --distribution-config (la risposta completa contiene anche l'ETag, che update-distribution non accetta).

$ # Capture the current ETag and the DistributionConfig body GET_ETAG=$(aws cloudfront get-distribution-config --id distribution-id \ --query 'ETag' --output text) aws cloudfront get-distribution-config --id distribution-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 --id distribution-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 --id distribution-id \ --query 'Distribution.Status' # Delete the distribution using the ETag from the update call. aws cloudfront delete-distribution --id distribution-id \ --if-match "$UPDATE_ETAG" # Fetch the OAC ETag, then delete the OAC. OAC_ETAG=$(aws cloudfront get-origin-access-control --id oac-id \ --query 'ETag' --output text) aws cloudfront delete-origin-access-control --id oac-id \ --if-match "$OAC_ETAG" aws s3control delete-access-point-policy \ --account-id account-id --name access-point-name aws s3 rm "s3://access-point-alias/content/sintel/" --recursive