Driver de áudio personalizado (Android)
Visão geral
O SDK do OpenTok para Android permite configurar um driver de áudio personalizado para emissores e assinantes. Você pode usar um driver de áudio personalizado para personalizar o áudio enviado ao fluxo de um emissor. Também é possível personalizar a reprodução do áudio dos fluxos assinados.
Configurando seu projeto
O código desta seção está disponível no projeto Basic-Audio-Driver-Java do exemplos-do-opentok-android-sdk repositório. Caso ainda não tenha feito isso, você precisará clonar o repositório em um diretório local. Na linha de comando, execute:
git clone git@github.com:Vonage/vonage-video-android-sdk-samples.git
Abra o Áudio Básico em Java projeto no Android Studio para acompanhar.
Observação: Este tutorial aborda a versão em Java do aplicativo de exemplo do Android. Para uma versão em Kotlin com documentação, consulte o Repositório de aplicativos de exemplo para Android.
Etapa 1: Adicionar um driver de áudio personalizado
Este aplicativo de exemplo utiliza o driver de áudio personalizado para transmitir ruído branco (um sinal de áudio aleatório) em seu fluxo de áudio. Ele também utiliza o driver de áudio personalizado para capturar o áudio de fluxos assinados e salvá-lo em um arquivo.
Configurando o dispositivo de áudio e o barramento de áudio
Ao utilizar um driver de áudio personalizado, você define um driver de áudio personalizado e um barramento de áudio a ser usado pelo aplicativo.
O NoiseAudioDevice A classe define uma interface básica de dispositivo de áudio a ser utilizada pelo aplicativo. Ela estende a BaseAudioDevice classe, definida pelo SDK do OpenTok para Android. Para usar um driver de áudio personalizado, chame o AudioDeviceManager.setAudioDevice() método. Este exemplo configura o dispositivo de áudio como uma instância do NoiseAudioDevice classe:
AudioDeviceManager.setAudioDevice(noiseAudioDevice);
Use o AudioSettings classe, definida no SDK do OpenTok para Android, para definir o formato de áudio utilizado pelo driver de áudio personalizado. A NoiseAudioDevice() O construtor instancia dois AudioSettings instâncias — uma para o capturador de áudio personalizado e outra para o renderizador de áudio personalizado. Ele define a taxa de amostragem e o número de canais para cada um:
public NoiseAudioDevice(Context context) {
this.context = context;
captureSettings = new AudioSettings(SAMPLING_RATE, NUM_CHANNELS_CAPTURING);
rendererSettings = new AudioSettings(SAMPLING_RATE, NUM_CHANNELS_RENDERING);
capturerStarted = false;
rendererStarted = false;
audioDriverPaused = false;
capturerHandler = new Handler();
rendererHandler = new Handler();
}
O construtor também define algumas propriedades locais que indicam se o dispositivo está capturando ou renderizando. Além disso, ele define uma instância de Handler para processar o capturer Objeto executável.
O NoiseAudioDevice.getAudioBus() O método obtém o AudioBus instância utilizada por esse dispositivo de áudio, definida pelo NoiseAudioDevice.AudioBus classe. Use o AudioBus instância para enviar e receber amostras de áudio de e para uma sessão. O editor acessará o AudioBus objeto para obter as amostras de áudio. Os assinantes enviarão amostras de áudio (de fluxos assinados) para o objeto AudioBus.
Gravação de áudio para uso por uma editora
O BaseAudioDevice.startCapturer() O método é chamado quando o dispositivo de áudio deve começar a capturar o áudio a ser publicado. O NoiseAudioDevice A implementação desse método inicia o capturer thread a ser executado na fila após 1 segundo:
public boolean startCapturer() {
capturerStarted = true;
capturerHandler.postDelayed(capturer, capturerIntervalMillis);
return true;
}
O capturer A thread gera um buffer contendo amostras de dados aleatórios (ruído branco). Em seguida, ela chama a writeCaptureData() método do AudioBus objeto, que envia os samples para o barramento de áudio. O editor no aplicativo usa os samples enviados para o barramento de áudio para transmiti-los como áudio no fluxo publicado. Então, se uma captura ainda estiver em andamento (se o aplicativo estiver publicando), o capturer a thread é executada novamente após mais um segundo:
private Runnable capturer = new Runnable() {
@Override
public void run() {
capturerBuffer.rewind();
Random rand = new Random();
rand.nextBytes(capturerBuffer.array());
getAudioBus().writeCaptureData(capturerBuffer, SAMPLING_RATE);
if(capturerStarted && !audioDriverPaused) {
capturerHandler.postDelayed(capturer, capturerIntervalMillis);
}
}
};
A classe `AudioDevice` inclui outros métodos que são implementados pela classe `NoiseAudioDevice`. No entanto, este exemplo não realiza nenhuma ação relevante nesses métodos; portanto, eles não serão abordados nesta discussão.
Etapa 2: Adicionando um renderizador de áudio personalizado
Você implementará um renderizador de áudio simples para o áudio dos fluxos aos quais está inscrito.
O NoiseAudioDevice() O método construtor configura um arquivo para salvar o áudio recebido. Isso é feito simplesmente para ilustrar um uso do renderizador de áudio do driver de áudio personalizado. O aplicativo requer as seguintes permissões, definidas no AndroidManifest.xml arquivo:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
O BaseAudioDevice.initRenderer() O método é chamado quando o aplicativo inicializa o renderizador de áudio. O NoiseAudioDevice A implementação desse método instancia um novo objeto `File`, no qual o aplicativo gravará os dados de áudio:
@Override
public boolean initRenderer() {
rendererBuffer = ByteBuffer.allocateDirect(SAMPLING_RATE * 2); // Each sample has 2 bytes
File documentsDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
rendererFile = new File(documentsDirectory, "output.raw");
if (!rendererFile.exists()) {
try {
rendererFile.getParentFile().mkdirs();
rendererFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
O BaseAudioDevice.startRendering() O método é chamado quando o dispositivo de áudio deve começar a reproduzir o áudio dos fluxos aos quais está inscrito. O NoiseAudioDevice A implementação desse método inicia o capturer thread a ser executado na fila após 1 segundo:
@Override
public boolean startRenderer() {
rendererStarted = true;
rendererHandler.postDelayed(renderer, rendererIntervalMillis);
return true;
}
O renderer O thread obtém 1 segundo de áudio do barramento de áudio chamando a função readRenderData() método do AudioBus objeto. Em seguida, ele grava os dados de áudio no arquivo (para fins de amostragem). E, se o dispositivo de áudio ainda estiver sendo usado para reproduzir amostras de áudio, ele define um temporizador para executar o rendererHandler retomar o thread após 0,1 segundos:
private Handler rendererHandler;
private Runnable renderer = new Runnable() {
@Override
public void run() {
rendererBuffer.clear();
getAudioBus().readRenderData(rendererBuffer, SAMPLING_RATE);
try {
FileOutputStream stream = new FileOutputStream(rendererFile);
stream.write(rendererBuffer.array());
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (rendererStarted && !audioDriverPaused) {
rendererHandler.postDelayed(renderer, rendererIntervalMillis);
}
}
};
Este exemplo é intencionalmente simples para fins didáticos — ele apenas grava os dados de áudio em um arquivo. Em uma aplicação mais prática de um driver de áudio personalizado, você poderia usá-lo para reproduzir áudio em um dispositivo Bluetooth ou para processar o áudio antes de reproduzi-lo.
Parabéns! Você concluiu o tutorial sobre drivers de áudio personalizados para Android.
Você pode continuar experimentando e ajustando o código que desenvolveu aqui, ou conferir o Próximos passos abaixo.
Próximos passos
Quando terminar esta seção, continue desenvolvendo e aprimorando seu aplicativo OpenTok com estes recursos úteis:
- Noções básicas sobre a Video API — Se ainda não o fez, reserve alguns minutos para aprender exatamente como o OpenTok funciona
- Exemplos de código — uma coleção de aplicativos de exemplo que exploram diversos recursos e casos de uso do OpenTok
- Guias para desenvolvedores — documentação detalhada sobre todos os recursos e funcionalidades do OpenTok
- Tutoriais adicionais — guias passo a passo para a implementação de outros recursos e casos de uso do OpenTok
- Referência do SDK do Android — explore os métodos e eventos associados ao SDK do OpenTok para Android