Guida pratica: Caricamento (in tempo reale)
Guida pratica: Caricamento (in tempo reale)
Introduzione
Partendo da quanto abbiamo detto sui caricamenti di base, adesso vediamo come caricare in tempo reale le risorse mentre vengono create. Questo approccio consente di caricare i file durante la registrazione, il rendering o lo streaming prima di conoscerne le dimensioni finali.
L’API per i caricamenti in tempo reale fa sì che le risorse diventino riproducibili in Frame.io solo pochi secondi dopo il completamento della registrazione, il che migliora notevolmente l’efficienza del flusso di lavoro.
Video dimostrativo
Per un’anteprima rapida di questa funzionalità, guarda il nostro video dimostrativo, che mostra un rendering caricato da Adobe Media Encoder in tempo reale, con il video riproducibile in Frame.io solo 5 secondi dopo il completamento del rendering.
Prerequisiti
Se non l’hai già fatto, consulta la guida Implementazione C2C: configurazione. Avrai bisogno dell’access_token ottenuto durante il processo di autenticazione e autorizzazione. Per gli esempi, useremo la stessa risorsa di test della guida sui caricamenti di base. È consigliabile conoscere bene la guida ai caricamenti di base, poiché amplieremo questi concetti.
Creazione di una risorsa in tempo reale
I caricamenti in tempo reale iniziano con un processo diverso di creazione delle risorse. Durante la creazione della risorsa, imposta is_realtime_upload su true e ometti il parametro filesize (oppure impostalo su null), poiché la dimensione finale non è nota durante la creazione:
Specifica dell'endpoint API
La documentazione per /v2/devices/assets è disponibile qui.
Estensione e nome file
Le risorse in tempo reale richiedono un’estensione file. Se il nome file non è noto durante la creazione della risorsa, puoi usare il campo extension (formato: '.mp4'). Questo approccio è preferibile se prevedi di aggiornare il nome della risorsa in seguito.
La risposta per le risorse in tempo reale è semplificata rispetto alla creazione delle risorse standard:
Nota che upload_urls è assente: per i caricamenti in tempo reale, genereremo degli URL di caricamento on-demand durante la creazione del file.
Richiesta di un URL di caricamento
Richiediamo un URL per la prima metà del nostro file (10.568.125 byte), usando l’asset_id della risposta precedente:
Specifica dell'endpoint API
La documentazione per /v2/devices/assets/{asset_id}/realtime_upload/parts è disponibile qui.
Informazioni sui parametri della richiesta:
-
parts: un elenco di parti di caricamento per cui sono necessari gli URL. Richiedi più URL in una singola chiamata per migliorare l’efficienza. -
number: il numero di parte sequenziale, a partire da 1. I numeri possono essere saltati e le parti possono essere caricate in qualsiasi ordine, ma vengono assemblate in sequenza. Non può superare 10.000 (limite AWS). *size: dimensione della parte in byte. Deve rispettare le restrizioni di caricamento multi-parte di AWS. *is_final: indica se questa è la parte finale del file.
La risposta contiene gli URL di caricamento richiesti:
L’elenco di upload_url corrisponde direttamente all’ordine della richiesta parts.
Adesso carica il primo chunk come indicato nella guida al caricamento di base:
Poi richiedi un URL per la seconda e ultima parte:
Prendi nota di queste aggiunte importanti:
is_finalè impostato sutrueper l’ultima parte, a indicare che il caricamento sarà completo dopo questo chunkasset_filesizefornisce la dimensione totale del file, richiesta quandois_final: trueper qualsiasi parte
Dopo aver ricevuto l’URL nella risposta:
Carica il chunk finale:
Gestione della parte finale
Quando viene caricata la parte finale, Frame.io inizia ad assemblare il file completo. Questo processo include un periodo di tolleranza di 60 secondi per il completamento delle parti rimanenti. Consigliamo di caricare la parte finale solo dopo aver caricato tutte le altre parti.
Ecco fatto! Vai su Frame.io per visualizzare la risorsa in tempo reale caricata. 🎉
Gestione dei nomi delle risorse
Se il nome del file non è noto durante la creazione della risorsa, puoi usare il campo extension senza specificare un nome (name):
Il sistema assegnerà un nome predefinito:
Puoi aggiornare questo nome includendo un campo asset_name quando richiedi gli URL di caricamento:
Il nome si aggiornerà solo se la risorsa ha ancora il nome predefinito; la richiesta verrà ignorata se è stata rinominata nell’interfaccia Frame.io o se è stata aggiornata in precedenza.
Ottimizzazione delle richieste URL
Per efficienza, richiedi gli URL per tutte le parti per cui disponi attualmente di dati, piuttosto che individualmente. Questo approccio è particolarmente utile per file di grandi dimensioni dove la velocità di caricamento potrebbe essere inferiore alla generazione dei dati.
Gestione delle intestazioni dei file media
Alcuni formati media richiedono intestazioni all’inizio del file che non vengono scritte finché l’intero file non viene completato. Questo crea una problema quando l’intestazione è più piccola della dimensione minima delle parti di AWS di 5 MiB (5.242.880 byte).
Consigliamo quanto segue:
- Riserva i primi 5.242.880 byte di dati del media senza caricarli
- Inizia a caricare le parti iniziando con
part_number=2 - Quando il file è completo, anteponi l’intestazione ai dati riservati
- Richiedi un URL per
part_number=1e carica questo chunk combinato
Questo approccio assicura che il primo chunk rispetti il requisito della dimensione minima, preservando la struttura corretta del file.
Scalare la dimensione delle parti per prestazioni ottimali
AWS impone dei limiti che influenzano la strategia di caricamento:
- Dimensione massima del file: 5 TiB (5.497.558.138.880 byte)
- Numero massimo di parti: 10.000
- Dimensione minima delle parti: 5 MiB (5.242.880 byte)
Una dimensione fissa delle parti crea alcuni compromessi:
- L’uso della dimensione minima (5 MiB) per tutte le 10.000 parti limita la dimensione totale del file a circa 52,4 GB
- Distribuire uniformemente la dimensione massima del file richiederebbe chunk di circa 550 MB, troppo grandi per lo streaming efficiente di file più piccoli
Serve una formula che bilanci questi vincoli, iniziando con parti piccole per caricamenti dinamici e garantendo al contempo di poter gestire file molto grandi se necessario.
Formula consigliata per la dimensione delle parti
Ecco il nostro approccio suggerito in Python:
… dove part_number è compreso tra 1 e 10_000 incluso, mentre format_bytes_per_second è il numero medio previsto di byte che il file dovrebbe consumare per secondo. Più avanti spieghiamo come abbiamo calcolato questa formula.
Valore scalare
La variabile scalar e il calcolo potrebbero risultare un po’ confusi a prima vista, ma si tratta di uno strumento matematico che garantisce che, indipendentemente dal valore usato per format_bytes_per_second, se inseriamo tutti i valori part_number consentiti da 1 a 10_0000 nella funzione, riceveremo un insieme di valori che restituisce esattamente il limite di dimensione file di 5 TiB (ovviamente nel modo più esatto possibile). Più avanti spiegheremo i nostri calcoli per arrivare a questa formula.
Arrotondamento per difetto
Usando l’arrotondamento per difetto, alcuni byte non verranno utilizzati, ma garantiamo che l’arrotondamento normale oltre 10.000 parti non ci faccia superare accidentalmente la dimensione massima consentita del file. Al massimo, verranno lasciati inutilizzati 10.000 byte (o 10 KB), il che è un compromesso accettabile.
Ecco le caratteristiche importanti di questa formula:
- Quando carichi 10.000 parti, la quantità totale di dati caricati sarà entro 10 KB del nostro limite di dimensione file di 5 TiB.
- L’operazione è ottimizzata per payload più piccoli ed efficienti all’inizio, in modo da aumentare la reattività per clip di durata medio-breve.
- Le clip molto lunghe avranno una reattività ridotta tra la fine della scrittura di un file e il momento in cui diventa riproducibile nel fotogramma.
Il compromesso tra il secondo e il terzo punto è mitigato dal fatto che la maggior parte delle clip non raggiungerà la dimensione in cui entra in gioco il terzo punto. Stiamo scambiando una maggiore reattività della MAGGIOR PARTE dei file con una minore reattività di pochissimi file.
Una versione più avanzata ed efficiente della nostra formula (che genera una funzione anonima part_size_calculator in cui sono precalcolati e incorporati il valore scalare statico e la velocità di trasmissione dei dati) potrebbe essere simile a questa:
Come funziona la formula.
Analizziamo le caratteristiche di output della formula in alto per vari tipi di file comuni.
Esempio 1: formato web
Per i formati riproducibili sul web con una velocità di circa 5,3 MB/s o inferiore (la maggior parte dei file H.264/H.265/HEVC), otterremo una progressione della dimensione del payload simile a questa:
Questi valori sono ben bilanciati per i caricamenti in tempo reale, specialmente per codec di riproduzione web come H.264; la maggior parte sarà sotto i 10,7 GB e, perciò, sarà completa entro 1.000 parti. La dimensione del payload non supererebbe mai i 21,6 MB.
Se elaborassimo metà delle nostre parti, la dimensione del payload non supererebbe comunque mai i 413,5 MB. Il caricamento raggiungerebbe un totale di 707 GB, più che sufficiente per la stragrande maggioranza dei file web.
È solo quando ci avviciniamo alla fine del numero di parti consentite che la dimensione del file inizia a crescere molto. Tuttavia, non supera mai 1,7 GB, ben al di sotto del limite AWS di 5 GiB per parte.
Esempio 2: Prores 422 LT. Prores 422 LT ha una velocità dati di 102 Mbps e genera una tabella come questa:
Questa tabella mostra delle proprietà utili rispetto alla formula ottimizzata per il web. Nelle prime 1.000 parti possiamo caricare 8 GB in più di file. I payload iniziali più grandi significano che non sarà necessario richiedere URL troppo rapidamente all’inizio, rendendo il caricamento più efficiente per la velocità di dati più elevata. La dimensione del payload verso la fine del processo di caricamento rimane elevata.
Esempio 2: Camera Raw
Infine, proviamo un formato Camera RAW che ha una velocità di dati di 280 MB/s. Con dati che arrivano così velocemente, provare a caricare in chunk da 5 MiB all’inizio semplicemente non ha senso:
I payload iniziali non sono solo più efficienti, ma stiamo risparmiando oltre mezzo gigabyte nella fascia superiore, rendendo le chiamate di rete meno suscettibili a eventi di rete avversi.
Mostrare il lavoro svolto
Prima di unire tutto in un esempio di uploader, vediamo come siamo arrivati alla nostra formula.
Dovevamo elaborare una formula che scambiasse payload grandi e pesanti alla fine delle parti consentite (che la maggior parte dei caricamenti non raggiungerà mai) con payload leggeri ed efficienti all’inizio, in cui ogni caricamento può trarne vantaggio. Allo stesso tempo, volevamo assicurarci che il nostro algoritmo arrivasse nell’ordine di grandezza del limite di 5 TiB proprio al numero di parte 10.000.
È qui che entra in gioco il calcolo infinitesimale.
Vogliamo che il grafo cresca esponenzialmente, quindi la formula dovrebbe probabilmente assomigliare a quanto segue:
… dove n è il numero della parte. Vogliamo anche assicurarci che ogni parte corrisponda, come minimo, alla velocità di trasferimento dei dati per la nostra formula, che chiameremo r:
Ora dobbiamo trovare una formula che ci dica la somma di questa formula per i primi 10.000 numeri naturali (1, 2, 3 …). Il simbolo sigma Σ indica la somma. Aggiungiamolo alla nostra formula:
… e ridefiniamo n come la serie di numeri naturali tra 1 e 10.000 (incluso). L’equazione non ci è ancora molto utile. Ha la forma intuitiva giusta, ma se impostiamo n=10.000 e r=5.242.880 come vogliamo, otteniamo semplicemente un risultato: 385.812.135.000 (385 GB). Il risultato non è solo molto al di sotto del nostro limite di dimensione file di 5 TiB, ma non c’è modo di manipolare la formula per ottenere quel risultato.
Vediamo di perfezionare la formula:
… dove x è un valore scalare che possiamo risolvere per ottenere 5 TiB come risultato. Ora possiamo impostare l’equazione in modo che sia uguale al nostro limite di dimensione file e risolvere per x:
Spesso, le somme devono essere risolte in modo iterativo, come in un loop for o while. In realtà, esiste una formula perfetta per il nostro caso: un modo noto per calcolare a basso costo la somma del quadrato per i primi n numeri naturali:
Basta riorganizzarla in un polinomio per renderla più facile da osservare:
Possiamo aggiungere le nostre variabili, x e r, su entrambi i lati:
E infine impostiamo la nostra nuova formula uguale a 5 TiB:
Ora tutto quello che dobbiamo fare è risolvere per x impostando n=10.000, ovvero il conteggio totale delle parti. Questo ci darà un modo per calcolare un valore scalare statico per una determinata velocità di trasferimento dei dati. Invece di farlo a mano inseriamolo in Wolfram Alpha:
Ora sì che stiamo ottenendo dei risultati! Se la velocità di trasferimento dei dati fosse la dimensione minima della parte (5 MiB), otterremmo un valore scalare statico pari a:
Nell’ambito informatico, questo rappresenta un valore float64 di 16,33293799427617. La nostra formula per determinare la dimensione della parte in questa Istanza sarebbe:
dove s è la dimensione della nostra parte.
Abbiamo ancora un altro problema. Nel mondo reale, non possiamo avere un payload con byte non interi. Dobbiamo arrotondare ogni valore. Useremo Python e eseguiremo l’arrotondamento per difetto:
Siamo arrivati a un esempio concreto della funzione originale fornita in questa guida.
Creazione di un uploader di base
Diamo un’occhiata ad un semplice pseudocodice simile a Python per caricare un file che viene sottoposto a rendering in tempo reale, utilizzando tutto quello che abbiamo imparato in questa guida:
Caricamento avanzato
Il codice precedente mostra solo il flusso di base per caricare un file in tempo reale. In realtà, questa logica deve essere migliorata con la gestione degli errori e tecniche di caricamento avanzato.
Avanti
I caricamenti in tempo reale sono un modo per rendere l’integrazione più dinamica possibile, con le risorse che diventano riproducibili in Frame.io pochi secondi dopo essere state registrate. In una guida successiva si parlerà delle tecniche e dei requisiti avanzati di caricamento. Anche se è scritta pensando ai caricamenti di base, la maggior parte della guida sarà comunque applicabile ai caricamenti in tempo reale.
Se non l’hai già fatto, ti incoraggiamo a contattare il nostro team, poi continua con la prossima guida. A presto!