> This page is for Da videocamera a cloud.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# 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](https://f.io/qjwfGmTa), 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](./implementing-c2c-setting-up). Avrai bisogno dell'`access_token` ottenuto durante il [processo di autenticazione e autorizzazione](./implementing-c2c-authentication-and-authorization). Per gli esempi, useremo la stessa [risorsa di test](https://f.io/Rq1q5CzB) della guida sui caricamenti di base. È consigliabile conoscere bene la [guida ai caricamenti di base](./how-to-basic-upload), 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:

```shell
{
curl -X POST https://api.frame.io/v2/devices/assets \
    --header 'Authorization: Bearer [access_token]' \
    --header 'Content-Type: application/json' \
    --header 'x-client-version: 2.0.0' \
    --data-binary @- <<'__JSON__' 
        {
            "name": "C2C_TEST_CLIP.mp4", 
            "filetype": "video/mp4", 
            "is_realtime_upload": true
        }
__JSON__
} | python -m json.tool
```




<Info title="Specifica dell'endpoint API">
  La documentazione per `/v2/devices/assets` è [disponibile qui](/camera-to-cloud/api-reference/device-asset-create).
</Info>

<Warning title="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.
</Warning>


La risposta per le risorse in tempo reale è semplificata rispetto alla creazione delle risorse standard:





```json
{
    "id": "{asset_id}",
    "name": "C2C_TEST_CLIP.mp4"
}
```

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:

```shell
{
curl -X POST https://api.frame.io/v2/devices/assets/{asset_id}/realtime_upload/parts \
    --header 'Authorization: Bearer [access_token]' \
    --header 'Content-Type: application/json' \
    --header 'x-client-version: 2.0.0' \
    --data-binary @- <<'__JSON__' 
        {
            "parts": [
                {
                    "number": 1,
                    "size": 10568125,
                    "is_final": false
                }
            ]
        }
__JSON__
} | python -m json.tool
```




<Info title="Specifica dell'endpoint API">
  La documentazione per `/v2/devices/assets/{asset_id}/realtime_upload/parts` è [disponibile qui](/camera-to-cloud/api-reference/device-create-realtime-upload-parts).
</Info>


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](https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html). * `is_final`: indica se questa è la parte finale del file.

La risposta contiene gli URL di caricamento richiesti:





```json
{
    "upload_urls": [
        "https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_01_path]"
    ]
}
```

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:





```shell
head -c 10568125 ~/Downloads/C2C_TEST_CLIP.mp4 | \
curl -X PUT https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_01_path] \
        --include \
        --header 'content-type: video/mp4' \
        --header 'x-amz-acl: private' \
        --data-binary @-
```





Poi richiedi un URL per la seconda e ultima parte:





```shell
{
curl -X POST https://api.frame.io/v2/devices/assets/{asset_id}/realtime_upload/parts \
    --header 'Authorization: Bearer [access_token]' \
    --header 'Content-Type: application/json' \
    --header 'x-client-version: 2.0.0' \
    --data-binary @- <<'__JSON__' 
        {
            "asset_filesize": 21136250,
            "parts": [
                {
                    "number": 2,
                    "size": 10568125,
                    "is_final": true
                }
            ]
        }
__JSON__
} | python -m json.tool
```





Prendi nota di queste aggiunte importanti:




* `is_final` è impostato su `true` per l'ultima parte, a indicare che il caricamento sarà completo dopo questo chunk
* `asset_filesize` fornisce la dimensione totale del file, richiesta quando `is_final: true` per qualsiasi parte




Dopo aver ricevuto l'URL nella risposta:





```json
{
    "upload_urls": [
        "https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_02_path]"
    ]
}
```





Carica il chunk finale:





```shell
tail -c 10568125 ~/Downloads/C2C_TEST_CLIP.mp4 | \
curl -X PUT https://frameio-uploads-production.s3-accelerate.amazonaws.com/parts/[part_02_path] \
        --include \
        --header 'content-type: video/mp4' \
        --header 'x-amz-acl: private' \
        --data-binary @-
```




<Warning title="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.



</Warning>


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

```shell
{
curl -X POST https://api.frame.io/v2/devices/assets \
    --header 'Authorization: Bearer [access_token]' \
    --header 'Content-Type: application/json' \
    --header 'x-client-version: 2.0.0' \
    --data-binary @- <<'__JSON__' 
        {
            "extension": ".mp4", 
            "filetype": "video/mp4", 
            "is_realtime_upload": true
        }
__JSON__
} | python -m json.tool
```





Il sistema assegnerà un nome predefinito:





```json
{
    "id": "{asset_id}",
    "name": "[new file].mp4"
}
```

Puoi aggiornare questo nome includendo un campo `asset_name` quando richiedi gli URL di caricamento:

```shell
{
curl -X POST https://api.frame.io/v2/devices/assets/{asset_id}/realtime_upload/parts \
    --header 'Authorization: Bearer [access_token]' \
    --header 'Content-Type: application/json' \
    --header 'x-client-version: 2.0.0' \
    --data-binary @- <<'__JSON__' 
        {
            "asset_name": "C2C_TEST_CLIP.mp4",
            "asset_filesize": 21136250,
            "parts": [
                {
                    "number": 2,
                    "size": 10568125,
                    "is_final": true
                }
            ]
        }
__JSON__
} | python -m json.tool
```





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:




1. Riserva i primi 5.242.880 byte di dati del media senza caricarli
2. Inizia a caricare le parti iniziando con `part_number=2`
3. Quando il file è completo, anteponi l'intestazione ai dati riservati
4. Richiedi un URL per `part_number=1` e 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:





**`Python`**

```python title="Python"
import math
from typing import Callable

# Constants
MINIMUM_PART_SIZE = 5_242_880
MAXIMUM_PART_COUNT = 10_000
MAXIMUM_FILE_SIZE = 5_497_558_138_880

# Maximum uniform data rate that allows for 10,000 parts
MAXIMUM_DATA_RATE = MAXIMUM_FILE_SIZE // MAXIMUM_PART_COUNT

def part_size(part_number: int, format_bytes_per_second: int) -> int:
    """
    Returns the payload size for a specific part number given the file's
    expected data rate.
    """
    if part_number < 1:
        raise ValueError("part_number must be greater than 0")

    if part_number > 10_000:
        raise ValueError("part_number must be less than 10,000")

    # Make sure we never go above the maximum data rate or fall below the
    # minimum part size, even if the data rate is lower.
    data_rate = min(format_bytes_per_second, MAXIMUM_DATA_RATE)
    data_rate = max(data_rate, MINIMUM_PART_SIZE)

    # Calculate a scalar given our data rate. We will explain this step
    # futher on in the guides.
    scalar = -(2 * (125 * data_rate - 68_719_476_736)) / 8_334_583_375
    part_size = math.floor(scalar * pow(part_number, 2)) + data_rate

    return part_size

```

... 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](/camera-to-cloud/how-to-upload-realtime#showing-our-work) spieghiamo come abbiamo calcolato questa formula.
<Info title="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](/camera-to-cloud/how-to-upload-realtime#showing-our-work) per arrivare a questa formula.
</Info>

<Info title="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.



</Info>


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:

**`Python`**

```python title="Python"
def create_part_size_calculator(format_bytes_per_second: int) -> Callable[[int], int]:
    """
    Returns a function that takes in a `part_number` and returns a
    `part_size` based on `data_rate`.
    """

    # Make sure we never go above the maximum data rate or fall below the
    # minimum part size, even if the data rate is lower.
    data_rate = min(format_bytes_per_second, MAXIMUM_DATA_RATE)
    data_rate = max(data_rate, MINIMUM_PART_SIZE)

    static_scalar = -(2 * (125 * data_rate - 68_719_476_736)) / 8_334_583_375

    def part_size_calculator(part_number: int) -> int:
        """Calculates size in bytes of upload for `part_number`."""
        if part_number < 1:
            raise ValueError("part_number must be greater than 0")

        if part_number > 10_000:
            raise ValueError("part_number must be less than 10,000")

        return math.floor(static_scalar * pow(part_number, 2) + data_rate)

    return part_size_calculator

```





### 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:




| Parti totali | Byte del payload | MB del payload | Byte totali del file | GB totali del file |
| ----------: | ------------: | ---------: | ----------------: | -------------: |
| 1 | 5.242.896 | 5,2 MB | 5.242.896 | 0,0 GB |
| 1.000 | 21.575.817 | 21,6 MB | 10.695.361.357 | 10,7 GB |
| 5.000 | 413.566.329 | 413,6 MB | 706.957.655.928 | 707,0 GB |
| 10.000 | 1.638.536.679 | 1.638,5 MB | 5.497.558.133.921 | 5.497,6 GB |
**Legenda delle colonne della tabella** - `Parti totali`: il numero totale di parti del file caricate su AWS. - `Byte del payload`: la dimensione del payload AWS PUT quando `part_number` è uguale a `Parti totali`. - `MB del payload`: come `Byte del payload`, ma in megabyte. - `Byte totali del file`: il numero totale di byte caricati per il file quando sono state caricate parti sequenziali per `Parti totali`. - `GB totali del file`: come `Byte totali del file`, ma in GB.

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](https://www.wolframalpha.com/input?i=-%282+%28-68%2C719%2C476%2C736+%2B+125+12%2C750%2C000%29%29%2F8%2C334%2C583%2C375) e genera una tabella come questa:
| Parti totali | Byte del payload | MB del payload | Byte totali del file | GB totali del file |
| ----------: | ------------: | ---------: | ----------------: | -------------: |
| 1 | 12.750.016 | 12,8 MB | 12.750.016 | 0,0 GB |
| 1.000 | 28.857.758 | 28,9 MB | 18.127.308.783 | 18,1 GB |
| 5.000 | 415.443.954 | 415,4 MB | 735.107.948.432 | 735,1 GB |
| 10.000 | 1.623.525.817 | 1.623,5 MB | 5.497.558.133.958 | 5.497,6 GB |




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:




| Parti totali | Byte del payload | MB del payload | Byte totali del file | GB totali del file |
| ----------: | ------------: | ---------: | ----------------: | -------------: |
| 1 | 280.000.008 | 280,0 MB | 280.000.008 | 0,3 GB |
| 1.000 | 288.091.460 | 288,1 MB | 282.701.200.139 | 282,7 GB |
| 5.000 | 482.286.516 | 482,3 MB | 1.737.245.341.542 | 1.737,2 GB |
| 10.000 | 1.089.146.065 | 1.089,1 MB | 5.497.558.133.870 | 5.497,6 GB |




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:





```math
n^2
```

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

```math
n^2 + 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:

```math
Σxn^2 + r
```

... 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](https://www.wolframalpha.com/input?i=%CE%A3n%5E2+%2B+r+where+n+%3D+1+to+10%2C000+and+r+%3D+5%2C242%2C880): `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:





```math
Σxn^2 + r
```

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

```math
Σxn^2 + r = 5,497,558,138,880
```

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](https://www.math-only-math.com/sum-of-the-squares-of-first-n-natural-numbers.html) per calcolare a basso costo la somma del quadrato per i primi `n` numeri naturali:

```math
Σn^2 = n(n+1)(2n+1)/6
```





Basta riorganizzarla in un polinomio per renderla più facile da osservare:





```math
Σn^2 = (2n^3 + 3n^2 + n)/6
```

Possiamo aggiungere le nostre variabili, `x` e `r`, su entrambi i lati:

```math
Σxn^2 + r = x(2n^3 + 3n^2 + n)/6 + rn
```





E infine impostiamo la nostra nuova formula uguale a 5 TiB:





```math
x(2n^3 + 3n^2 + n)/6 + rn = 5,497,558,138,880
```

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](https://www.wolframalpha.com/input?i=x%282n%5E3+%2B+3n%5E2+%2B+n%29%2F6+%2B+r+*+n+%3D+5%2C497%2C558%2C138%2C880+solve+for+x+where+n+%3D+10%2C000):

```math
x = -(2 (125 r - 68719476736)) / 8334583375
```

Ora sì che stiamo ottenendo dei risultati! Se la velocità di trasferimento dei dati fosse la dimensione minima della parte (5 MiB), [otterremmo](https://www.wolframalpha.com/input?i=x%282n%5E3+%2B+3n%5E2+%2B+n%29%2F6+%2B+r+*+n+%3D+5%2C497%2C558%2C138%2C880+solve+for+x+where+n+%3D+10%2C000+and+r+%3D+5%2C242%2C880) un valore scalare statico pari a:

```math
136,128,233,472 / 8,334,583,375
```

Nell'ambito informatico, questo rappresenta un valore float64 di `16,33293799427617`. La nostra formula per determinare la dimensione della parte in questa Istanza sarebbe:

```math
s = 16.33293799427617n^2 + 5,242,880
```

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:





**`Python`**

```python title="Python"
math.floor(16.33293799427617 * pow(part_number, 2)) + 5_242_880
```





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:





**`Python`**

```python title="Python"
import math
from datetime import datetime, timezone
from typing import Callable

# The minimum size, in bytes, for a single, non-final part upload.
MINIMUM_PART_SIZE = 5_242_880
# The maximum filesize in
MAXIMUM_PART_COUNT = 10_000
# The maximum size, in bytes, for an AWS upload.
MAXIMUM_FILE_SIZE = 5_497_558_138_880

# The data rate at which every part is an equal size, and could not
# be any uniformly larger without violating the maximum total file
# size if 10_000 parts were to be uploaded. it works out to
# ~549.8 MB per payload. By enforcing this we actually never need
# to check if a part exceeds the maximum allowed part size, as our
# parts will never exceed ~549.8 MB.
MAXIMUM_DATA_RATE = MAXIMUM_FILE_SIZE // MAXIMUM_PART_COUNT

def create_part_size_calculator(format_bytes_per_second: int) -> Callable[[int], int]:
    """
    Returns a function that takes in a `part_number` and returns a
    `part_size` based on `data_rate`.
    """
    ...

def upload_render(data_stream: DataStream, channel: int = 0) -> None:
    """
    Uploads an asset for data_stream, which is a custom IO class that pulls remaining
    upload data from an internal buffer or file, depending on how well the upload is
    keeping pace with the render.

    Uploads to `channel`
    """

    asset = c2c.asset_create(
        extension=data_stream.extension, 
        filetype=data_stream.mimetpye, 
        channel=channel,
        offset=datetime.now(timezone.utc) - data_stream.created_at()
    )

    calculate_part_size = create_part_size_calculator(data_stream.data_rate())
    next_part_number = 0

    while True:
        next_payload_size = calculate_part_size(next_part_number)

        # Waits until one or more chunks worth of data is ready for upload. Cache 
        # whether our data stream has completed writing the file, and the current 
        # number of bytes we have remaining to upload at this time.
        available_bytes, stream_complete = data_stream.wait_for_available_data(
            minimum_bytes=next_payload_size
        )

        # Build the list of parts to request based on our available data.
        parts = []
        while available_bytes > 0:
            payload_size = calculate_part_size(next_part_number)

            if available_bytes < payload_size and not stream_complete:
                break

            payload_size = min(payload_size, available_bytes)

            parts.append(
                c2c.RealtimeUploadPart(
                    part_number=next_part_number,
                    part_size=payload_size,
                    is_final=False
                )
            )

            available_bytes -= payload_size
            next_part_number += 1

        # If our stream is done writing, mark the last part as final.
        if stream_complete:
            parts[-1].is_final = True

        # Create the part URLs using the C2C endpoint.
        response = c2c.create_realtime_parts(
            asset_id=asset.id,
            asset_name=None if not stream_complete else data_stream.filename,
            asset_filesize=None if not stream_complete else data_stream.size(),
            parts=parts
        )

        # Upload each part to its URL.
        for part, part_url in zip(parts, response.upload_urls):
            part_data = data_stream.read(bytes=part.size)
            c2c.upload_chunk(part_data, part_url, data_stream.mimetype)

        if stream_complete:
            break

```




<Warning title="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](/camera-to-cloud/how-to-handle-errors) e tecniche di [caricamento avanzato](/camera-to-cloud/how-to-advanced-uploads).
</Warning>


## 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](/camera-to-cloud/how-to-advanced-uploads) 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!