

# SDK di trasmissione IVS: guida per Android \$1 Streaming a bassa latenza
<a name="broadcast-android"></a>

L'SDK di trasmissione a bassa latenza IVS per Android fornisce le interfacce necessarie per trasmettere ad Amazon IVS su Android.

Il pacchetto `com.amazonaws.ivs.broadcast` implementa l'interfaccia descritta in questo documento. Sono supportate le seguenti operazioni: 
+ Impostare (inizializzare) una sessione di trasmissione. 
+ Gestire la trasmissione.
+ Collegare e scollegare dispositivi di input.
+ Gestire una sessione di composizione. 
+ Ricevere eventi. 
+ Ricevere errori. 

**Ultima versione dell'SDK di trasmissione Android:** 1.40.0 ([Note di rilascio](https://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/release-notes.html#mar12-26-broadcast-android-ll)) 

**Documentazione di riferimento:** per informazioni sui metodi più importanti disponibili nell'SDK di trasmissione di Amazon IVS per Android, consulta la documentazione di riferimento all'indirizzo [https://aws.github.io/amazon-ivs-'-docs/1.40.0/android/](https://aws.github.io/amazon-ivs-broadcast-docs/1.40.0/android/).

**Codice di esempio:** vedere il repository di esempio Android su GitHub: [https://github.com/aws-samples/amazon-ivs-'-android-sample](https://github.com/aws-samples/amazon-ivs-broadcast-android-sample).

**Requisiti della piattaforma:** Android 9.0\$1

# Guida introduttiva all'SDK di trasmissione IVS per Android \$1 Streaming a bassa latenza
<a name="broadcast-android-getting-started"></a>

Questo documento illustra i passaggi necessari per iniziare a utilizzare l'SDK di trasmissione per lo streaming a bassa latenza di Amazon IVS per Android.

## Installare la libreria
<a name="broadcast-android-install"></a>

Per aggiungere la libreria di trasmissione di Amazon IVS per Android al proprio ambiente di sviluppo Android, aggiungere la libreria al file `build.gradle` come mostrato di seguito (per l'ultima versione dell'SDK di trasmissione di Amazon IVS):

```
repositories {
    mavenCentral()
}
dependencies {
     implementation 'com.amazonaws:ivs-broadcast:1.40.0'
}
```

In alternativa, per installare manualmente l'SDK, scaricare la versione più recente da questo percorso:
+ [https://search.maven.org/artifact/com.amazonaws/ivs-broadcast](https://search.maven.org/artifact/com.amazonaws/ivs-broadcast)

## Utilizzo dell'SDK con i simboli di debug
<a name="broadcast-android-using-debug-symbols-ll"></a>

Pubblichiamo anche una versione dell'SDK di trasmissione per Android che include i simboli di debug. È possibile utilizzare questa versione per migliorare la qualità dei report di debug (tracce dello stack) in Firebase Crashlytics se si verificano arresti anomali nell'SDK di trasmissione IVS, ad esempio `libbroadcastcore.so`. Quando segnali questi arresti anomali al team dell'SDK di IVS, le tracce dello stack di qualità superiore facilitano la risoluzione dei problemi.

Per utilizzare questa versione dell'SDK, inserisci quanto segue nei tuoi file di build di Gradle:

```
implementation "com.amazonaws:ivs-broadcast:$version:unstripped@aar"
```

Utilizza la riga precedente invece di questa:

```
implementation "com.amazonaws:ivs-broadcast:$version@aar"
```

### Caricamento dei simboli in Firebase Crashlytics
<a name="android-debug-symbols-ll-firebase-crashlytics"></a>

Assicurati che i tuoi file di build Gradle siano configurati per Firebase Crashlytics. Segui le istruzioni di Google qui:

[https://firebase.google.com/docs/crashlytics/ndk-reports](https://firebase.google.com/docs/crashlytics/ndk-reports)

Assicurati di includere `com.google.firebase:firebase-crashlytics-ndk` come dipendenza.

Quando crei l'app per il rilascio, il plug-in Firebase Crashlytics dovrebbe caricare i simboli automaticamente. Per caricare i simboli manualmente, esegui uno dei comandi seguenti:

```
gradle uploadCrashlyticsSymbolFileRelease
```

```
./gradlew uploadCrashlyticsSymbolFileRelease
```

Non è un problema se i simboli vengono caricati due volte, automaticamente e manualmente.

### Impedire che .apk Release diventi più grande
<a name="android-debug-symbols-ll-sizing-apk"></a>

Prima di impacchettare il file `.apk` di rilascio, il plug-in Android Gradle tenta automaticamente di rimuovere le informazioni di debug dalle librerie condivise (inclusa la libreria `libbroadcastcore.so` dell'SDK di trasmissione IVS). Tuttavia, a volte ciò non accade. Di conseguenza, il file `.apk` potrebbe diventare più grande e si potrebbe ricevere un messaggio di avviso dal plug-in Android Gradle che indica che non è in grado di rimuovere i simboli di debug e sta impacchettando i file `.so` così come sono. In tal caso, segui questa procedura:
+ Installa un NDK per Android. Va bene qualsiasi versione recente.
+ Aggiungi `ndkVersion <your_installed_ndk_version_number>` al file `build.gradle` dell'applicazione. Fallo anche se l'applicazione non contiene codice nativo.

Per ulteriori informazioni, consulta questo [report sul problema](https://issuetracker.google.com/issues/353554169).

## Creare il listener di eventi
<a name="broadcast-android-create-event-listener"></a>

La configurazione di un listener di eventi consente di ricevere aggiornamenti di stato, notifiche di modifica del dispositivo, errori e informazioni sull'audio della sessione.

```
BroadcastSession.Listener broadcastListener = 
          new BroadcastSession.Listener() {
    @Override
    public void onStateChanged(@NonNull BroadcastSession.State state) {
        Log.d(TAG, "State=" + state);
    }

    @Override
    public void onError(@NonNull BroadcastException exception) {
        Log.e(TAG, "Exception: " + exception);
    }
};
```

## Richiedere autorizzazioni
<a name="broadcast-android-permissions"></a>

L'app deve richiedere l'autorizzazione per accedere alla fotocamera e al microfono dell'utente. (Questo non riguarda solo Amazon IVS, ma qualsiasi applicazione che abbia bisogno di accedere alle fotocamere e ai microfoni.)

Qui, controlliamo se l'utente ha già concesso le autorizzazioni e, in caso contrario, le chiediamo:

```
final String[] requiredPermissions =
         { Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO };

for (String permission : requiredPermissions) {
    if (ContextCompat.checkSelfPermission(this, permission) 
                != PackageManager.PERMISSION_GRANTED) {
        // If any permissions are missing we want to just request them all.
        ActivityCompat.requestPermissions(this, requiredPermissions, 0x100);
        break;
    }
}
```

Qui, otteniamo la risposta dell'utente:

```
@Override
public void onRequestPermissionsResult(int requestCode, 
                                      @NonNull String[] permissions,
                                      @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode,
               permissions, grantResults);
    if (requestCode == 0x100) {
        for (int result : grantResults) {
            if (result == PackageManager.PERMISSION_DENIED) {
                return;
            }
        }
        setupBroadcastSession();
    }
}
```

## Creare la sessione di trasmissione
<a name="broadcast-android-create-session"></a>

L'interfaccia di trasmissione è `com.amazonaws.ivs.broadcast.BroadcastSession`. Inizializzarla con un preset, come mostrato di seguito. Se si verificano errori durante l'inizializzazione (ad esempio un errore nella configurazione di un codec), `BroadcastListener` mostrerà un messaggio di errore e `broadcastSession.isReady` sarà `false`.

**Importante:** tutte le chiamate all'SDK di trasmissione Amazon IVS per Android *devono* essere eseguite sul thread su cui viene istanziato l'SDK. *L'esecuzione di una chiamata da un thread diverso causerà un errore irreversibile dell'SDK e interromperà la trasmissione*.

```
// Create a broadcast-session instance and sign up to receive broadcast
// events and errors.
Context ctx = getApplicationContext();
broadcastSession = new BroadcastSession(ctx,
                       broadcastListener,
                       Presets.Configuration.STANDARD_PORTRAIT,
                       Presets.Devices.FRONT_CAMERA(ctx));
```

Consultare anche [Creare la sessione di trasmissione (versione avanzata)](broadcast-android-use-cases.md#broadcast-android-create-session-advanced).

## Impostare ImagePreviewView per l'anteprima
<a name="broadcast-android-set-imagepreviewview"></a>

Se si desidera visualizzare un'anteprima per un dispositivo fotocamera attivo, aggiungere un'anteprima `ImagePreviewView` per il dispositivo dalla gerarchia delle visualizzazioni.

```
// awaitDeviceChanges will fire on the main thread after all pending devices 
// attachments have been completed
broadcastSession.awaitDeviceChanges(() -> {
    for(Device device: session.listAttachedDevices()) {
        // Find the camera we attached earlier
        if(device.getDescriptor().type == Device.Descriptor.DeviceType.CAMERA) {
            LinearLayout previewHolder = findViewById(R.id.previewHolder);
            ImagePreviewView preview = ((ImageDevice)device).getPreviewView();
            preview.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT));
            previewHolder.addView(preview);
        }
    }
});
```

## Avviare una trasmissione
<a name="broadcast-android-start"></a>

Al nome host che si riceve nel campo di risposta `ingestEndpoint` dell'operazione `GetChannel` è necessario anteporre `rtmps://` e posporre `/app`. L'URL completo deve essere in questo formato: `rtmps://{{ ingestEndpoint }}/app`

```
broadcastSession.start(IVS_RTMPS_URL, IVS_STREAMKEY);
```

L'SDK di trasmissione Android supporta solo l'acquisizione RTMPS (non l'acquisizione RTMP non sicura).

## Interrompere una trasmissione
<a name="broadcast-android-stop"></a>

```
broadcastSession.stop();
```

## Rilasciare una sessione di trasmissione
<a name="broadcast-android-release-session"></a>

Quando il lettore non è più in uso *deve essere invocato* il metodo `broadcastSession.release()`, per liberare le risorse utilizzate dalla libreria.

```
@Override
protected void onDestroy() {
    super.onDestroy();
    previewHolder.removeAllViews();
    broadcastSession.release();
}
```

# Casi d'uso avanzati per l'SDK di trasmissione IVS per Android \$1 Streaming a bassa latenza
<a name="broadcast-android-use-cases"></a>

Qui presentiamo alcuni casi d'uso avanzati. Iniziare con la configurazione di base di cui sopra e continuare qui. 

## Creare la configurazione di trasmissione
<a name="broadcast-android-create-configuration"></a>

Qui creiamo una configurazione personalizzata con due slot mixer che ci permettono di associare due fonti video al mixer. Uno (`custom`) è a schermo intero e disposto dietro l'altro (`camera`), che è più piccolo e si trova nell'angolo in basso a destra. Per lo slot `custom` non impostiamo una posizione, una dimensione o una modalità di aspetto. Poiché non impostiamo questi parametri, lo slot utilizzerà le impostazioni del video per le dimensioni e la posizione.

```
BroadcastConfiguration config = BroadcastConfiguration.with($ -> {
    $.audio.setBitrate(128_000);
    $.video.setMaxBitrate(3_500_000);
    $.video.setMinBitrate(500_000);
    $.video.setInitialBitrate(1_500_000);
    $.video.setSize(1280, 720);
    $.mixer.slots = new BroadcastConfiguration.Mixer.Slot[] {
            BroadcastConfiguration.Mixer.Slot.with(slot -> {
                // Do not automatically bind to a source
                slot.setPreferredAudioInput(
                           Device.Descriptor.DeviceType.UNKNOWN);
                // Bind to user image if unbound
                slot.setPreferredVideoInput(
                           Device.Descriptor.DeviceType.USER_IMAGE);
                slot.setName("custom");
                return slot;
            }),
            BroadcastConfiguration.Mixer.Slot.with(slot -> {
                slot.setzIndex(1);
                slot.setAspect(BroadcastConfiguration.AspectMode.FILL);
                slot.setSize(300, 300);
                slot.setPosition($.video.getSize().x - 350,
                        $.video.getSize().y - 350);
                slot.setName("camera");
                return slot;
            })
    };
    return $;
});
```

## Creare la sessione di trasmissione (versione avanzata)
<a name="broadcast-android-create-session-advanced"></a>

Creare una `BroadcastSession` come è stato fatto nell'[esempio di base](broadcast-android-getting-started.md#broadcast-android-create-session), ma fornire qui la propria configurazione personalizzata. Inoltre, inserire `null` per l'array dei dispositivi, perché lo aggiungeremo manualmente.

```
// Create a broadcast-session instance and sign up to receive broadcast
// events and errors.
Context ctx = getApplicationContext();
broadcastSession = new BroadcastSession(ctx,
                       broadcastListener,
                       config, // The configuration we created above
                       null); // We’ll manually attach devices after
```

## Iterare e collegare un dispositivo fotocamera
<a name="broadcast-android-attach-camera"></a>

Qui iteriamo attraverso i vari dispositivi di input rilevati dall'SDK. Su Android 7 (Nougat) questo restituirà solo i dispositivi microfonici predefiniti, perché l'SDK di trasmissione di Amazon IVS non supporta la selezione di dispositivi non predefiniti su questa versione di Android.

Una volta trovato un dispositivo che vogliamo usare, chiamiamo `attachDevice` per collegarlo. Una funzione lambda viene richiamata sul thread principale una volta che il collegamento del dispositivo di input è stato completato. In caso di errore, si riceverà una segnalazione nel listener.

```
for(Device.Descriptor desc: BroadcastSession.listAvailableDevices(getApplicationContext())) {
    if(desc.type == Device.Descriptor.DeviceType.CAMERA &&
            desc.position == Device.Descriptor.Position.FRONT) {
        session.attachDevice(desc, device -> {
            LinearLayout previewHolder = findViewById(R.id.previewHolder);
            ImagePreviewView preview = ((ImageDevice)device).getPreviewView();
            preview.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT));
            previewHolder.addView(preview);
            // Bind the camera to the mixer slot we created above.
            session.getMixer().bind(device, "camera");
        });
        break;
    }
}
```

## Scambiare fotocamere
<a name="broadcast-android-swap-cameras"></a>

```
// This assumes you’ve kept a reference called "currentCamera" that points to
// a front facing camera
for(Device device: BroadcastSession.listAvailableDevices()) {
   if(device.type == Device.Descriptor.DeviceType.CAMERA &&
          Device.position != currentCamera.position) {
        // Remove the preview view for the old device.
        // setImagePreviewTextureView is an example function 
        // that handles your view hierarchy.
        setImagePreviewView(null);
        session.exchangeDevices(currentCamera, device, camera -> {
             // Set the preview view for the new device.
             setImagePreviewView(camera.getPreviewView());
             currentCamera = camera;
        });
        break;
   }
}
```

## Creare una superficie di input
<a name="broadcast-android-create-input-surface"></a>

Per inserire dati audio o immagini generati dall'app, utilizzare `createImageInputSource` o `createAudioInputSource`. Entrambi questi metodi creano e collegano dispositivi virtuali che possono essere associati al mixer come qualsiasi altro dispositivo.

La `SurfaceSource` restituita da `createImageInputSource` dispone di un metodo `getInputSurface` che darà un `Surface` che utilizzabile con l'API Camera2, OpenGL o Vulkan, o qualsiasi altra cosa che può scrivere su una superficie.

Il `AudioDevice` restituito da `createAudioInputSource` può ricevere dati PCM lineari generati da AudioRecorder o altri mezzi.

```
SurfaceSource source = session.createImageInputSource();
Surface surface = source.getInputSurface();
session.getMixer().bind(source, “custom”);
```

## Scollegare un dispositivo
<a name="broadcast-android-detach-device"></a>

Se si desidera scollegare e non sostituire un dispositivo, scollegarlo con `Device` o `Device.Descriptor`.

```
session.detachDevice(currentCamera);
```

## Acquisire l'audio dello schermo e del sistema
<a name="broadcast-android-screen-audio-capture"></a>

L'SDK di trasmissione di Amazon IVS per Android include alcuni strumenti che semplificano la cattura dell'audio dello schermo del dispositivo (Android 6 e versioni successive) e del sistema (Android 10 e versioni successive). Se si desidera gestirli manualmente si può creare una fonte di ingresso immagine personalizzata e una fonte di ingresso audio personalizzata.

Per creare una sessione di acquisizione dell'audio dello schermo e del sistema, si avrà bisogno innanzitutto di creare una formula per la richiesta di autorizzazione:

```
public void startScreenCapture() {
    MediaProjectionManager manager =
                         (MediaProjectionManager) getApplicationContext()
                         .getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    if(manager != null) {
        Intent intent = manager.createScreenCaptureIntent();
        startActivityIfNeeded(intent, SCREEN_CAPTURE_REQUEST_ID);
    }
}
```

Per utilizzare questa funzionalità è necessario fornire una classe che estenda `com.amazonaws.ivs.broadcast.SystemCaptureService`. Non è necessario sovrascrivere nessuno dei suoi metodi, ma la classe deve essere specificata per evitare potenziali collisioni tra i servizi.

È necessario anche aggiungere un paio di elementi al proprio manifest Android:

```
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application ...>
    <service android:name=".ExampleSystemCaptureService"
         android:foregroundServiceType="mediaProjection" 
         android:isolatedProcess="false" />
</application>
...
```

La classe che estende `SystemCaptureService` deve essere denominata nell'elemento `<service>`. Su Android 9 e versioni successive, `foregroundServiceType` deve essere `mediaProjection`.

Una volta ottenuta una risposta alla formula di autorizzazione, si può procedere con la creazione della sessione di acquisizione dell'audio dello schermo e del sistema. Su Android 8 e versioni successive, è necessario fornire una notifica da visualizzare nel Pannello notifiche dell'utente. L'SDK di trasmissione di Amazon IVS per Android fornisce il metodo di convenienza `createServiceNotificationBuilder`. In alternativa, è possibile fornire la propria notifica. 

```
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode != SCREEN_CAPTURE_REQUEST_ID
       || Activity.RESULT_OK != resultCode) {
        return;
    }
    Notification notification = null;
    if(Build.VERSION.SDK_INT >= 26) {
        Intent intent = new Intent(getApplicationContext(),
                                   NotificationActivity.class);
        notification = session
                         .createServiceNotificationBuilder("example",
                                            "example channel", intent)
                         .build();
    }
    session.createSystemCaptureSources(data,
                  ExampleSystemCaptureService.class,
                  Notification,
                  devices -> {
        // This step is optional if the mixer slots have been given preferred
        // input device types SCREEN and SYSTEM_AUDIO
        for (Device device : devices) {
            session.getMixer().bind(device, "game");
        }
    });
}
```

## Ottenere impostazioni di trasmissione suggerite
<a name="broadcast-android-recommended-settings"></a>

Per valutare la connessione dell'utente prima di avviare una trasmissione, utilizzare il metodo `recommendedVideoSettings` per eseguire un breve test. Durante l'esecuzione del test, si riceveranno vari suggerimenti ordinati dal più consigliato al meno raccomandato. In questa versione dell'SDK, non è possibile riconfigurare l'attuale `BroadcastSession`, quindi effettuare `release()` e crearne uno nuovo con le impostazioni suggerite. Si continuerà a ricevere `BroadcastSessionTest.Results` fino a che `Result.status` è `SUCCESS` o `ERROR`. È possibile controllare lo stato di avanzamento mediante `Result.progress`.

Amazon IVS supporta un bitrate massimo di 8,5 Mb/s (per i canali il cui `type` è `STANDARD` o `ADVANCED`), quindi il `maximumBitrate` restituito da questo metodo non supera mai 8,5 Mb/s. Per tenere in considerazione le piccole fluttuazioni nelle prestazioni di rete, il `initialBitrate` suggerito restituito da questo metodo è leggermente inferiore al bitrate reale misurato nel test. (Solitamente è sconsigliabile utilizzare il 100% della larghezza di banda disponibile.)

```
void runBroadcastTest() {
    this.test = session.recommendedVideoSettings(RTMPS_ENDPOINT, RTMPS_STREAMKEY,
        result -> {
            if (result.status == BroadcastSessionTest.Status.SUCCESS) {
                this.recommendation = result.recommendations[0];
            }
        });
}
```

## Utilizzo della riconnessione automatica
<a name="broadcast-android-auto-reconnect"></a>

IVS supporta la riconnessione automatica a una trasmissione se la trasmissione si interrompe inaspettatamente senza chiamare l'API `stop`, ad esempio in caso di perdita temporanea della connettività di rete. Per abilitare la riconnessione automatica, chiama `setEnabled(true)` su `BroadcastConfiguration.autoReconnect`.

Quando qualcosa causa l'interruzione imprevista del flusso, l'SDK riprova fino a 5 volte, seguendo una strategia di backoff lineare. Notifica all'applicazione lo stato del nuovo tentativo tramite il metodo `BroadcastSession.Listener.onRetryStateChanged`.

Dietro le quinte, la riconnessione automatica utilizza la funzionalità [stream-takeover](streaming-config.md#streaming-config-stream-takeover) di IVS aggiungendo un numero di priorità, che inizia con 1, alla fine della chiave di flusso fornita. Per tutta la durata dell'istanza `BroadcastSession`, tale numero viene incrementato di 1 ogni volta che viene tentata una riconnessione. Ciò significa che se la connessione del dispositivo viene interrotta 4 volte durante una trasmissione e ogni perdita richiede 1-4 nuovi tentativi, la priorità dell'ultimo flusso in uscita potrebbe essere compresa tra 5 e 17. Per questo motivo, *consigliamo di non utilizzare l'acquisizione del flusso IVS da un altro dispositivo se per lo stesso canale nell'SDK è abilitata la riconnessione automatica*. Non ci sono garanzie sulla priorità utilizzata dall'SDK in quel momento e l'SDK proverà a riconnettersi con una priorità più alta se un altro dispositivo prende il controllo.

## Uso dei microfoni Bluetooth
<a name="broadcast-android-bluetooth-microphones"></a>

Per trasmettere utilizzando dispositivi microfonici Bluetooth, è necessario avviare una connessione Bluetooth SCO:

```
Bluetooth.startBluetoothSco(context);
// Now bluetooth microphones can be used
…
// Must also stop bluetooth SCO
Bluetooth.stopBluetoothSco(context);
```

# Problemi noti e soluzioni alternative per l'SDK di trasmissione IVS per Android \$1 Streaming a bassa latenza
<a name="broadcast-android-issues"></a>

Questo documento elenca i problemi noti che potresti riscontrare durante l'utilizzo dell'SDK di trasmissione dello streaming a bassa latenza di Amazon IVS per Android e suggerisce possibili soluzioni alternative.
+ L'utilizzo di un microfono esterno collegato tramite Bluetooth può generare instabilità. Quando un dispositivo Bluetooth viene collegato o scollegato durante una sessione di trasmissione, l'ingresso del microfono potrebbe smettere di funzionare fino a quando il dispositivo non viene effettivamente scollegato e ricollegato.

  **Soluzione alternativa:** se si prevede di utilizzare un auricolare Bluetooth, collegarlo prima di avviare la trasmissione e lasciarlo connesso per tutta la durata della trasmissione.
+ L'SDK di trasmissione non supporta l'accesso su fotocamere esterne collegate tramite USB.

  **Soluzione alternativa:** non utilizzare fotocamere esterne collegate tramite USB. 
+ L'invio di dati audio più velocemente rispetto al tempo reale (utilizzando una fonte audio personalizzata) determina la perdita di sincronizzazione dell'audio.

  **Soluzione alternativa:** non inviare dati audio a una velocità superiore al tempo reale. 
+ I dispositivi Android 6 e 7 non possono ricevere le richiamate `onDeviceAdded` e `onDeviceRemoved` dell'SDK di trasmissione per i microfoni poiché queste versioni di Android consentono solo l'uso del microfono predefinito di sistema.

  **Soluzione alternativa:** per questi dispositivi, l'SDK di trasmissione utilizza il microfono di default del sistema.
+ Quando una `ImagePreviewView` viene rimossa da un elemento padre (ad esempio, `removeView()` viene chiamato dall'elemento padre), `ImagePreviewView` viene rilasciata immediatamente. `ImagePreviewView` non mostra alcun frame quando viene aggiunta a un'altra vista principale.

  **Soluzione alternativa:** richiedi un'altra anteprima utilizzando `getPreview`.
+ Alcuni codificatori video Android non possono essere configurati con dimensioni video inferiori a 176x176. La configurazione di una dimensione inferiore causa un errore e impedisce lo streaming.

  **Soluzione alternativa:** configura la dimensione del video in modo che non sia inferiore a 176x176.
+ L'attivazione dei B-frame può migliorare la qualità della compressione; tuttavia alcuni codificatori forniscono un controllo del bitrate meno preciso quando i B-frame sono abilitati, il che può causare problemi durante le fluttuazioni della rete.

  **Soluzione alternativa:** considerare la possibilità di disattivare i B-frame se, per il caso d'uso specifico, l'aderenza costante del bitrate è più importante dell'efficienza di compressione.