mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-04-22 04:25:01 +00:00
Add --audio-bit-rate option
Add an option to configure the audio bit-rate.
This commit is contained in:
parent
637683ed7a
commit
4dbb7aa685
10 changed files with 46 additions and 6 deletions
|
@ -19,6 +19,12 @@ provides display and control of Android devices connected on USB (or over TCP/IP
|
|||
.B \-\-always\-on\-top
|
||||
Make scrcpy window always on top (above other windows).
|
||||
|
||||
.TP
|
||||
.BI "\-\-audio\-bit\-rate " value
|
||||
Encode the audio at the given bit\-rate, expressed in bits/s. Unit suffixes are supported: '\fBK\fR' (x1000) and '\fBM\fR' (x1000000).
|
||||
|
||||
Default is 196K (196000).
|
||||
|
||||
.TP
|
||||
.BI "\-b, \-\-bit\-rate " value
|
||||
Encode the video at the given bit\-rate, expressed in bits/s. Unit suffixes are supported: '\fBK\fR' (x1000) and '\fBM\fR' (x1000000).
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#define OPT_NO_POWER_ON 1039
|
||||
#define OPT_CODEC 1040
|
||||
#define OPT_NO_AUDIO 1041
|
||||
#define OPT_AUDIO_BIT_RATE 1042
|
||||
|
||||
struct sc_option {
|
||||
char shortopt;
|
||||
|
@ -99,6 +100,14 @@ static const struct sc_option options[] = {
|
|||
.longopt = "always-on-top",
|
||||
.text = "Make scrcpy window always on top (above other windows).",
|
||||
},
|
||||
{
|
||||
.longopt_id = OPT_AUDIO_BIT_RATE,
|
||||
.longopt = "audio-bit-rate",
|
||||
.argdesc = "value",
|
||||
.text = "Encode the audio at the given bit-rate, expressed in bits/s. "
|
||||
"Unit suffixes are supported: 'K' (x1000) and 'M' (x1000000).\n"
|
||||
"Default is 196K (196000).",
|
||||
},
|
||||
{
|
||||
.shortopt = 'b',
|
||||
.longopt = "bit-rate",
|
||||
|
@ -1424,6 +1433,11 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case OPT_AUDIO_BIT_RATE:
|
||||
if (!parse_bit_rate(optarg, &opts->audio_bit_rate)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case OPT_CROP:
|
||||
opts->crop = optarg;
|
||||
break;
|
||||
|
|
|
@ -28,6 +28,7 @@ const struct scrcpy_options scrcpy_options_default = {
|
|||
},
|
||||
.max_size = 0,
|
||||
.bit_rate = 0,
|
||||
.audio_bit_rate = 0,
|
||||
.max_fps = 0,
|
||||
.lock_video_orientation = SC_LOCK_VIDEO_ORIENTATION_UNLOCKED,
|
||||
.rotation = 0,
|
||||
|
|
|
@ -109,6 +109,7 @@ struct scrcpy_options {
|
|||
struct sc_shortcut_mods shortcut_mods;
|
||||
uint16_t max_size;
|
||||
uint32_t bit_rate;
|
||||
uint32_t audio_bit_rate;
|
||||
uint16_t max_fps;
|
||||
enum sc_lock_video_orientation lock_video_orientation;
|
||||
uint8_t rotation;
|
||||
|
|
|
@ -357,6 +357,7 @@ scrcpy(struct scrcpy_options *options) {
|
|||
.tunnel_port = options->tunnel_port,
|
||||
.max_size = options->max_size,
|
||||
.bit_rate = options->bit_rate,
|
||||
.audio_bit_rate = options->audio_bit_rate,
|
||||
.max_fps = options->max_fps,
|
||||
.lock_video_orientation = options->lock_video_orientation,
|
||||
.control = options->control,
|
||||
|
|
|
@ -221,6 +221,8 @@ execute_server(struct sc_server *server,
|
|||
}
|
||||
if (!params->audio) {
|
||||
ADD_PARAM("audio=false");
|
||||
} else if (params->audio_bit_rate) {
|
||||
ADD_PARAM("audio_bit_rate=%" PRIu32, params->audio_bit_rate);
|
||||
}
|
||||
if (params->codec != SC_CODEC_H264) {
|
||||
ADD_PARAM("codec=%s", sc_server_get_codec_name(params->codec));
|
||||
|
|
|
@ -34,6 +34,7 @@ struct sc_server_params {
|
|||
uint16_t tunnel_port;
|
||||
uint16_t max_size;
|
||||
uint32_t bit_rate;
|
||||
uint32_t audio_bit_rate;
|
||||
uint16_t max_fps;
|
||||
int8_t lock_video_orientation;
|
||||
bool control;
|
||||
|
|
|
@ -40,12 +40,12 @@ public final class AudioEncoder {
|
|||
private static final String MIMETYPE = MediaFormat.MIMETYPE_AUDIO_OPUS;
|
||||
private static final int SAMPLE_RATE = 48000;
|
||||
private static final int CHANNELS = 2;
|
||||
private static final int BIT_RATE = 196000;
|
||||
|
||||
private static final int BUFFER_MS = 15; // milliseconds
|
||||
private static final int BUFFER_SIZE = SAMPLE_RATE * CHANNELS * BUFFER_MS / 1000;
|
||||
|
||||
private final Streamer streamer;
|
||||
private final int bitRate;
|
||||
|
||||
private AudioRecord recorder;
|
||||
private MediaCodec mediaCodec;
|
||||
|
@ -63,8 +63,9 @@ public final class AudioEncoder {
|
|||
|
||||
private boolean ended;
|
||||
|
||||
public AudioEncoder(Streamer streamer) {
|
||||
public AudioEncoder(Streamer streamer, int bitRate) {
|
||||
this.streamer = streamer;
|
||||
this.bitRate = bitRate;
|
||||
}
|
||||
|
||||
private static AudioFormat createAudioFormat() {
|
||||
|
@ -89,10 +90,10 @@ public final class AudioEncoder {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
private static MediaFormat createFormat() {
|
||||
private static MediaFormat createFormat(int bitRate) {
|
||||
MediaFormat format = new MediaFormat();
|
||||
format.setString(MediaFormat.KEY_MIME, MIMETYPE);
|
||||
format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
|
||||
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
|
||||
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNELS);
|
||||
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, SAMPLE_RATE);
|
||||
return format;
|
||||
|
@ -208,7 +209,7 @@ public final class AudioEncoder {
|
|||
mediaCodecThread = new HandlerThread("AudioEncoder");
|
||||
mediaCodecThread.start();
|
||||
|
||||
MediaFormat format = createFormat();
|
||||
MediaFormat format = createFormat(bitRate);
|
||||
mediaCodec.setCallback(new EncoderCallback(), new Handler(mediaCodecThread.getLooper()));
|
||||
mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ public class Options {
|
|||
private int maxSize;
|
||||
private VideoCodec codec = VideoCodec.H264;
|
||||
private int bitRate = 8000000;
|
||||
private int audioBitRate = 196000;
|
||||
private int maxFps;
|
||||
private int lockVideoOrientation = -1;
|
||||
private boolean tunnelForward;
|
||||
|
@ -82,6 +83,14 @@ public class Options {
|
|||
this.bitRate = bitRate;
|
||||
}
|
||||
|
||||
public int getAudioBitRate() {
|
||||
return audioBitRate;
|
||||
}
|
||||
|
||||
public void setAudioBitRate(int audioBitRate) {
|
||||
this.audioBitRate = audioBitRate;
|
||||
}
|
||||
|
||||
public int getMaxFps() {
|
||||
return maxFps;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ public final class Server {
|
|||
AudioEncoder audioEncoder = null;
|
||||
if (audio) {
|
||||
Streamer audioStreamer = new Streamer(connection.getAudioFd(), AudioCodec.OPUS, options.getSendCodecId(), options.getSendFrameMeta());
|
||||
audioEncoder = new AudioEncoder(audioStreamer);
|
||||
audioEncoder = new AudioEncoder(audioStreamer, options.getAudioBitRate());
|
||||
audioEncoder.start();
|
||||
}
|
||||
|
||||
|
@ -210,6 +210,10 @@ public final class Server {
|
|||
int bitRate = Integer.parseInt(value);
|
||||
options.setBitRate(bitRate);
|
||||
break;
|
||||
case "audio_bit_rate":
|
||||
int audioBitRate = Integer.parseInt(value);
|
||||
options.setAudioBitRate(audioBitRate);
|
||||
break;
|
||||
case "max_fps":
|
||||
int maxFps = Integer.parseInt(value);
|
||||
options.setMaxFps(maxFps);
|
||||
|
|
Loading…
Add table
Reference in a new issue