

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
<a name="tutorial-stream-video-with-cloudfront"></a>

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
<a name="tutorial-cf-how-it-works"></a>

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 immutabile`Cache-Control`.

## Prerequisiti
<a name="tutorial-cf-prerequisites"></a>
+ 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](fsxn-creating-access-points.md).
+ 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](https://ffmpeg.org/) installato localmente, per codificare il video di esempio in HLS.
+ Un file video sorgente. Questo tutorial utilizza il [trailer di Sintel](https://download.blender.org/durian/trailer/sintel_trailer-1080p.mp4) della Blender Foundation, una clip di 52 secondi a 1080p pubblicata con licenza Creative Commons.

## Passaggio 1: codifica il video sorgente come pacchetto HLS
<a name="tutorial-cf-encode"></a>

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
   ```

1. 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
<a name="tutorial-cf-upload"></a>

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-alias}}Sostituiscilo 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
<a name="tutorial-cf-oac"></a>

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
<a name="tutorial-cf-distribution"></a>

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 denominato`dist.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_100`utilizza 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 in`PriceClass_All`. Per ulteriori informazioni, vedi [Scelta della classe di prezzo per una CloudFront distribuzione](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PriceClass.html).

1. 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
<a name="tutorial-cf-ap-policy"></a>

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 denominato`ap-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}}"
               }
           }
       }]
   }
   ```

1. 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
<a name="tutorial-cf-verify"></a>

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-cache`intestazione 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 ](https://github.com/video-dev/hls.js)

## Estendere il pattern
<a name="tutorial-cf-extending"></a>
+ **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](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-procedures.html). 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](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html) 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
<a name="tutorial-cf-troubleshooting"></a>

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 abbiano`Content-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 cloudfront`su 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
<a name="tutorial-cf-clean-up"></a>

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 valori`get-distribution-config`: il `ETag` for `--if-match` e l'`DistributionConfig`oggetto 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
```