Casi d'uso avanzati per l'SDK di trasmissione IVS per Android | Streaming a bassa latenza - Amazon IVS

Casi d'uso avanzati per l'SDK di trasmissione IVS per Android | Streaming a bassa latenza

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

Creare la configurazione di trasmissione

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)

Creare una BroadcastSession come è stato fatto nell'esempio di base, 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

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

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

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

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

L'SDK di trasmissione di Amazon IVS per Android include alcuni strumenti che semplificano la cattura dell'audio dello schermo del dispositivo (Android 5 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"); } }); }

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

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

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);