Disable audio if device could not capture

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.
This commit is contained in:
Romain Vimont
2023-02-18 18:09:18 +01:00
parent 3038bf4c3b
commit 166257b808
6 changed files with 94 additions and 11 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);