Casos de uso avançados para o SDK de Transmissão para Android do IVS | Streaming de baixa latência
Aqui, apresentamos alguns casos de uso avançados. Comece com a configuração básica acima e continue aqui.
Criar uma configuração de transmissão do Android
Aqui, criamos uma configuração personalizada com dois slots de mixer que nos permitem vincular duas fontes de vídeo ao mixer. Um deles (custom
) é tela cheia e fica posicionado atrás do outro (camera
), que é menor e está localizado no canto inferior direito. Para o slot custom
, não definimos uma posição, um tamanho ou um modo de aspecto. Como não definimos esses parâmetros, o slot usará as configurações de vídeo para tamanho e posição.
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 $; });
Criar a sessão de transmissão (versão avançada)
Crie uma BroadcastSession
, como fez no exemplo básico, mas forneça sua configuração personalizada aqui. Forneça também null
para a matriz de dispositivos, pois vamos adicioná-los 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
Iterar e anexar um dispositivo de câmera
Aqui nós fazemos a iteração por meio dos dispositivos de entrada que o SDK detectou. No Android 7 (Nougat), retornará apenas dispositivos de microfone padrão, pois o Amazon IVS Broadcast SDK não é compatível com a seleção de dispositivos não padrão nesta versão do Android.
Depois de encontrarmos um dispositivo que queremos usar, chamamos attachDevice
para anexá-lo. Uma função lambda é chamada no thread principal quando o dispositivo de entrada termina de ser anexado. Em caso de falha, você receberá um erro no 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; } }
Trocar câmeras
// 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; } }
Criar uma superfície de entrada
Para inserir dados de som ou imagem gerados pela aplicação, use createImageInputSource
ou createAudioInputSource
. Os dois métodos criam e anexam dispositivos virtuais que podem ser vinculados ao mixer como qualquer outro dispositivo.
O SurfaceSource
retornado por createImageInputSource
tem um método getInputSurface
, que dará a você um Surface
que poderá ser utilizado com a API do Camera2, o OpenGL, o Vulkan ou qualquer outra coisa que possa gravar em Surface.
O AudioDevice
retornado por createAudioInputSource
pode receber dados de PCM linear gerados pelo AudioRecorder ou por outros meios.
SurfaceSource source = session.createImageInputSource(); Surface surface = source.getInputSurface(); session.getMixer().bind(source, “custom”);
Desconectar um dispositivo
Se você deseja desconectar e não substituir um dispositivo, desconecte-o com Device
ou Device.Descriptor
.
session.detachDevice(currentCamera);
Captura de tela e de áudio de sistema
O Amazon IVS Broadcast SDK for Android inclui alguns ajudantes que simplificam a captura de tela do dispositivo (Android 5 e posteriores) e áudio do sistema (Android 10 e posteriores). Se quiser gerenciá-los manualmente, você pode criar uma fonte de entrada de imagem personalizada e uma fonte de entrada de áudio personalizada.
Para criar uma sessão de captura de tela e de áudio de sistema, primeiro é necessário criar uma intenção de solicitação de permissão:
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); } }
Para usar esse recurso, é necessário fornecer uma classe que estenda com.amazonaws.ivs.broadcast.SystemCaptureService
. Não é necessário substituir nenhum de seus métodos, mas a classe precisa estar lá para evitar possíveis colisões entre serviços.
Você também deve adicionar alguns elementos a seu manifesto do Android:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <application ...> <service android:name=".ExampleSystemCaptureService" android:foregroundServiceType="mediaProjection" android:isolatedProcess="false" /> </application> ...
Sua classe que se estende SystemCaptureService
deve ser nomeada no elemento <service>
. No Android 9 e posteriores, o foregroundServiceType
deve ser mediaProjection
.
Depois que a intenção das permissões for retornada, será possível prosseguir com a criação da sessão de captura de tela e de áudio do sistema. No Android 8 e posteriores, é necessário fornecer uma notificação para ser exibida no painel de notificação do usuário. O Amazon IVS Broadcast SDK for Android fornece o método de conveniência createServiceNotificationBuilder
. Se preferir, você pode fornecer sua própria notificação.
@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"); } }); }
Obter configurações recomendadas de transmissão
Para avaliar a conexão do usuário antes de iniciar uma transmissão, use o método recommendedVideoSettings
para executar um breve teste. À medida que o teste for executado, você receberá várias recomendações, ordenadas da mais recomendada para a menos recomendada. Nesta versão do SDK, não é possível reconfigurar a BroadcastSession
atual, então você precisará release()
e criar uma nova com as configurações recomendadas. Você continuará recebendo BroadcastSessionTest.Results
até que Result.status
seja SUCCESS
ou ERROR
. É possível verificar o progresso com Result.progress
.
O Amazon IVS é compatível com uma taxa de bits de até 8,5 Mbps (para canais cujo type
seja STANDARD
ou ADVANCED
), de modo que a maximumBitrate
retornada por esse método nunca excede 8,5 Mbps. Para considerar pequenas flutuações da performance da rede, o initialBitrate
recomendado retornado por esse método é ligeiramente menor do que a taxa de bits verdadeira medida no teste. (Geralmente, não é aconselhável usar 100% da largura de banda disponível.)
void runBroadcastTest() { this.test = session.recommendedVideoSettings(RTMPS_ENDPOINT, RTMPS_STREAMKEY, result -> { if (result.status == BroadcastSessionTest.Status.SUCCESS) { this.recommendation = result.recommendations[0]; } }); }
Uso da reconexão automática
O IVS oferece suporte à reconexão automática a uma transmissão caso a transmissão pare inesperadamente sem chamar a API stop
; por exemplo, uma perda temporária na conectividade de rede. Para ativar a reconexão automática, chame setEnabled(true)
em BroadcastConfiguration.autoReconnect
.
Quando algo faz com que o fluxo pare inesperadamente, o SDK tenta novamente até 5 vezes, seguindo uma estratégia de recuo linear. Ele notifica sua aplicação sobre o estado da nova tentativa por meio do método BroadcastSession.Listener.onRetryStateChanged
.
Nos bastidores, a reconexão automática usa a funcionalidade de aquisição de fluxo do IVS, anexando um número de prioridade, começando com 1, ao final da chave de fluxo fornecida. Pela duração da instância BroadcastSession
, esse número é incrementado em 1 cada vez que uma reconexão é tentada. Isso significa que se a conexão do dispositivo for perdida 4 vezes durante uma transmissão e cada perda exigir de 1 a 4 tentativas, a prioridade da última transmissão poderá estar entre 5 e 17. Por isso, recomendamos que você não use a aquisição de fluxo do IVS a partir de outro dispositivo enquanto a reconexão automática estiver ativada no SDK para o mesmo canal. Não há garantias de qual prioridade o SDK estará usando no momento, e o SDK tentará se reconectar com uma prioridade mais alta se outro dispositivo assumir o controle.
Uso de microfones Bluetooth
Para transmitir usando microfones Bluetooth, você deve iniciar uma conexão por Bluetooth SCO:
Bluetooth.startBluetoothSco(context); // Now bluetooth microphones can be used … // Must also stop bluetooth SCO Bluetooth.stopBluetoothSco(context);