Disable audio on initialization error

By default, audio is enabled (--no-audio must be explicitly passed to
disable it).

However, some devices may not support audio capture (typically devices
below Android 11, or Android 11 when the shell application is not
foreground on start).

In that case, make the server notify the client to dynamically disable
audio forwarding so that it does not wait indefinitely for an audio
stream.

Also disable audio on unknown codec or missing decoder on the
client-side, for the same reasons.
This commit is contained in:
Romain Vimont
2023-02-18 18:09:18 +01:00
parent 07db9acba4
commit 4b6508edd6
6 changed files with 103 additions and 13 deletions

View File

@@ -200,19 +200,24 @@ public final class AudioEncoder {
@TargetApi(Build.VERSION_CODES.M)
public void encode() throws IOException {
mediaCodec = MediaCodec.createEncoderByType(MIMETYPE); // may throw IOException
try {
recorder = createAudioRecord();
try {
mediaCodec = MediaCodec.createEncoderByType(MIMETYPE); // may throw IOException
recorder = createAudioRecord();
mediaCodecThread = new HandlerThread("AudioEncoder");
mediaCodecThread.start();
mediaCodecThread = new HandlerThread("AudioEncoder");
mediaCodecThread.start();
MediaFormat format = createFormat();
mediaCodec.setCallback(new EncoderCallback(), new Handler(mediaCodecThread.getLooper()));
mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
MediaFormat format = createFormat();
mediaCodec.setCallback(new EncoderCallback(), new Handler(mediaCodecThread.getLooper()));
mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
recorder.startRecording();
recorder.startRecording();
} catch (Throwable e) {
// Notify the client that the audio could not be captured
streamer.writeDisableStream();
throw e;
}
inputThread = new Thread(() -> {
try {
@@ -243,7 +248,9 @@ public final class AudioEncoder {
inputThread.start();
outputThread.start();
} catch (Throwable e) {
mediaCodec.release();
if (mediaCodec != null) {
mediaCodec.release();
}
if (recorder != null) {
recorder.release();
}

View File

@@ -40,6 +40,12 @@ public final class Streamer {
}
}
public void writeDisableStream() throws IOException {
// Writing 0 (32-bit) as codec-id means that the device disables the stream (because it could not capture)
byte[] zeros = new byte[4];
IO.writeFully(fd, zeros, 0, zeros.length);
}
public void writePacket(ByteBuffer codecBuffer, MediaCodec.BufferInfo bufferInfo) throws IOException {
if (codec == AudioCodec.OPUS) {
fixOpusConfigPacket(codecBuffer, bufferInfo);