Add --audio-encoder option

Similar to --video-encoder, but for audio.
This commit is contained in:
Romain Vimont
2023-02-19 20:20:29 +01:00
parent cbe346e650
commit 2788e442b2
9 changed files with 60 additions and 5 deletions

View File

@@ -46,6 +46,7 @@ public final class AudioEncoder {
private final Streamer streamer;
private final int bitRate;
private final String encoderName;
// Capacity of 64 is in practice "infinite" (it is limited by the number of available MediaCodec buffers, typically 4).
// So many pending tasks would lead to an unacceptable delay anyway.
@@ -60,9 +61,10 @@ public final class AudioEncoder {
private boolean ended;
public AudioEncoder(Streamer streamer, int bitRate) {
public AudioEncoder(Streamer streamer, int bitRate, String encoderName) {
this.streamer = streamer;
this.bitRate = bitRate;
this.encoderName = encoderName;
}
private static AudioFormat createAudioFormat() {
@@ -210,14 +212,14 @@ public final class AudioEncoder {
boolean mediaCodecStarted = false;
boolean recorderStarted = false;
try {
String mimeType = streamer.getCodec().getMimeType();
mediaCodec = MediaCodec.createEncoderByType(mimeType); // may throw IOException
Codec codec = streamer.getCodec();
mediaCodec = createMediaCodec(codec, encoderName);
recorder = createAudioRecord();
mediaCodecThread = new HandlerThread("AudioEncoder");
mediaCodecThread.start();
MediaFormat format = createFormat(mimeType, bitRate);
MediaFormat format = createFormat(codec.getMimeType(), bitRate);
mediaCodec.setCallback(new EncoderCallback(), new Handler(mediaCodecThread.getLooper()));
mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
@@ -257,6 +259,8 @@ public final class AudioEncoder {
outputThread.start();
waitEnded();
} catch (ConfigurationException e) {
// Do not print stack trace, a user-friendly error-message has already been logged
} finally {
if (!recorderStarted) {
// Notify the client that the audio could not be captured
@@ -307,6 +311,21 @@ public final class AudioEncoder {
}
}
private static MediaCodec createMediaCodec(Codec codec, String encoderName) throws IOException, ConfigurationException {
if (encoderName != null) {
Ln.d("Creating audio encoder by name: '" + encoderName + "'");
try {
return MediaCodec.createByCodecName(encoderName);
} catch (IllegalArgumentException e) {
Ln.e(CodecUtils.buildUnknownEncoderMessage(codec, encoderName));
throw new ConfigurationException("Unknown encoder: " + encoderName);
}
}
MediaCodec mediaCodec = MediaCodec.createEncoderByType(codec.getMimeType());
Ln.d("Using audio encoder: '" + mediaCodec.getName() + "'");
return mediaCodec;
}
private class EncoderCallback extends MediaCodec.Callback {
@TargetApi(Build.VERSION_CODES.N)
@Override

View File

@@ -24,6 +24,7 @@ public class Options {
private boolean stayAwake;
private List<CodecOption> codecOptions;
private String encoderName;
private String audioEncoderName;
private boolean powerOffScreenOnClose;
private boolean clipboardAutosync = true;
private boolean downsizeOnError = true;
@@ -180,6 +181,14 @@ public class Options {
this.encoderName = encoderName;
}
public String getAudioEncoderName() {
return audioEncoderName;
}
public void setAudioEncoderName(String audioEncoderName) {
this.audioEncoderName = audioEncoderName;
}
public void setPowerOffScreenOnClose(boolean powerOffScreenOnClose) {
this.powerOffScreenOnClose = powerOffScreenOnClose;
}

View File

@@ -112,7 +112,7 @@ public final class Server {
if (audio) {
Streamer audioStreamer = new Streamer(connection.getAudioFd(), options.getAudioCodec(), options.getSendCodecId(),
options.getSendFrameMeta());
audioEncoder = new AudioEncoder(audioStreamer, options.getAudioBitRate());
audioEncoder = new AudioEncoder(audioStreamer, options.getAudioBitRate(), options.getAudioEncoderName());
audioEncoder.start();
}
@@ -264,6 +264,10 @@ public final class Server {
options.setEncoderName(value);
}
break;
case "audio_encoder_name":
if (!value.isEmpty()) {
options.setAudioEncoderName(value);
}
case "power_off_on_close":
boolean powerOffScreenOnClose = Boolean.parseBoolean(value);
options.setPowerOffScreenOnClose(powerOffScreenOnClose);