mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-04-22 20:45:01 +00:00
Add --require-audio
By default, scrcpy mirrors only the video when audio capture fails on the device. Add a flag to force scrcpy to fail if audio is enabled but does not work. PR #3757 <https://github.com/Genymobile/scrcpy/pull/3757>
This commit is contained in:
parent
81fb51e625
commit
fd0a82ba93
9 changed files with 47 additions and 15 deletions
|
@ -45,6 +45,7 @@ _scrcpy() {
|
|||
-r --record=
|
||||
--record-format=
|
||||
--render-driver=
|
||||
--require-audio
|
||||
--rotation=
|
||||
-s --serial=
|
||||
--shortcut-mod=
|
||||
|
|
|
@ -51,6 +51,7 @@ arguments=(
|
|||
{-r,--record=}'[Record screen to file]:record file:_files'
|
||||
'--record-format=[Force recording format]:format:(mp4 mkv)'
|
||||
'--render-driver=[Request SDL to use the given render driver]:driver name:(direct3d opengl opengles2 opengles metal software)'
|
||||
'--require-audio=[Make scrcpy fail if audio is enabled but does not work]'
|
||||
'--rotation=[Set the initial display rotation]:rotation values:(0 1 2 3)'
|
||||
{-s,--serial=}'[The device serial number \(mandatory for multiple devices only\)]:serial:($("${ADB-adb}" devices | awk '\''$2 == "device" {print $1}'\''))'
|
||||
'--shortcut-mod=[\[key1,key2+key3,...\] Specify the modifiers to use for scrcpy shortcuts]:shortcut mod:(lctrl rctrl lalt ralt lsuper rsuper)'
|
||||
|
|
|
@ -262,6 +262,10 @@ Supported names are currently "direct3d", "opengl", "opengles2", "opengles", "me
|
|||
.UR https://wiki.libsdl.org/SDL_HINT_RENDER_DRIVER
|
||||
.UE
|
||||
|
||||
.TP
|
||||
.B \-\-require\-audio
|
||||
By default, scrcpy mirrors only the video if audio capture fails on the device. This flag makes scrcpy fail if audio is enabled but does not work.
|
||||
|
||||
.TP
|
||||
.BI "\-\-rotation " value
|
||||
Set the initial display rotation. Possibles values are 0, 1, 2 and 3. Each increment adds a 90 degrees rotation counterclockwise.
|
||||
|
|
|
@ -69,6 +69,7 @@ enum {
|
|||
OPT_AUDIO_ENCODER,
|
||||
OPT_LIST_ENCODERS,
|
||||
OPT_LIST_DISPLAYS,
|
||||
OPT_REQUIRE_AUDIO,
|
||||
};
|
||||
|
||||
struct sc_option {
|
||||
|
@ -458,6 +459,13 @@ static const struct sc_option options[] = {
|
|||
.longopt_id = OPT_RENDER_EXPIRED_FRAMES,
|
||||
.longopt = "render-expired-frames",
|
||||
},
|
||||
{
|
||||
.longopt_id = OPT_REQUIRE_AUDIO,
|
||||
.longopt = "require-audio",
|
||||
.text = "By default, scrcpy mirrors only the video when audio capture "
|
||||
"fails on the device. This flag makes scrcpy fail if audio is "
|
||||
"enabled but does not work."
|
||||
},
|
||||
{
|
||||
.longopt_id = OPT_ROTATION,
|
||||
.longopt = "rotation",
|
||||
|
@ -1801,6 +1809,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||
case OPT_LIST_DISPLAYS:
|
||||
opts->list_displays = true;
|
||||
break;
|
||||
case OPT_REQUIRE_AUDIO:
|
||||
opts->require_audio = true;
|
||||
break;
|
||||
default:
|
||||
// getopt prints the error message on stderr
|
||||
return false;
|
||||
|
|
|
@ -176,14 +176,13 @@ run_demuxer(void *data) {
|
|||
struct sc_demuxer *demuxer = data;
|
||||
|
||||
// Flag to report end-of-stream (i.e. device disconnected)
|
||||
bool eos = false;
|
||||
enum sc_demuxer_status status = SC_DEMUXER_STATUS_ERROR;
|
||||
|
||||
uint32_t raw_codec_id;
|
||||
bool ok = sc_demuxer_recv_codec_id(demuxer, &raw_codec_id);
|
||||
if (!ok) {
|
||||
LOGE("Demuxer '%s': stream disabled due to connection error",
|
||||
demuxer->name);
|
||||
eos = true;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -191,7 +190,7 @@ run_demuxer(void *data) {
|
|||
LOGW("Demuxer '%s': stream explicitly disabled by the device",
|
||||
demuxer->name);
|
||||
sc_demuxer_disable_sinks(demuxer);
|
||||
eos = true;
|
||||
status = SC_DEMUXER_STATUS_DISABLED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -241,7 +240,7 @@ run_demuxer(void *data) {
|
|||
bool ok = sc_demuxer_recv_packet(demuxer, packet);
|
||||
if (!ok) {
|
||||
// end of stream
|
||||
eos = true;
|
||||
status = SC_DEMUXER_STATUS_EOS;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -272,7 +271,7 @@ run_demuxer(void *data) {
|
|||
finally_close_sinks:
|
||||
sc_demuxer_close_sinks(demuxer);
|
||||
end:
|
||||
demuxer->cbs->on_ended(demuxer, eos, demuxer->cbs_userdata);
|
||||
demuxer->cbs->on_ended(demuxer, status, demuxer->cbs_userdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,15 @@ struct sc_demuxer {
|
|||
void *cbs_userdata;
|
||||
};
|
||||
|
||||
enum sc_demuxer_status {
|
||||
SC_DEMUXER_STATUS_EOS,
|
||||
SC_DEMUXER_STATUS_DISABLED,
|
||||
SC_DEMUXER_STATUS_ERROR,
|
||||
};
|
||||
|
||||
struct sc_demuxer_callbacks {
|
||||
void (*on_ended)(struct sc_demuxer *demuxer, bool eos, void *userdata);
|
||||
void (*on_ended)(struct sc_demuxer *demuxer, enum sc_demuxer_status,
|
||||
void *userdata);
|
||||
};
|
||||
|
||||
// The name must be statically allocated (e.g. a string literal)
|
||||
|
|
|
@ -72,6 +72,7 @@ const struct scrcpy_options scrcpy_options_default = {
|
|||
.start_fps_counter = false,
|
||||
.power_on = true,
|
||||
.audio = true,
|
||||
.require_audio = false,
|
||||
.list_encoders = false,
|
||||
.list_displays = false,
|
||||
};
|
||||
|
|
|
@ -154,6 +154,7 @@ struct scrcpy_options {
|
|||
bool start_fps_counter;
|
||||
bool power_on;
|
||||
bool audio;
|
||||
bool require_audio;
|
||||
bool list_encoders;
|
||||
bool list_displays;
|
||||
};
|
||||
|
|
|
@ -218,12 +218,15 @@ sc_recorder_on_ended(struct sc_recorder *recorder, bool success,
|
|||
}
|
||||
|
||||
static void
|
||||
sc_video_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos,
|
||||
void *userdata) {
|
||||
sc_video_demuxer_on_ended(struct sc_demuxer *demuxer,
|
||||
enum sc_demuxer_status status, void *userdata) {
|
||||
(void) demuxer;
|
||||
(void) userdata;
|
||||
|
||||
if (eos) {
|
||||
// The device may not decide to disable the video
|
||||
assert(status != SC_DEMUXER_STATUS_DISABLED);
|
||||
|
||||
if (status == SC_DEMUXER_STATUS_EOS) {
|
||||
PUSH_EVENT(SC_EVENT_DEVICE_DISCONNECTED);
|
||||
} else {
|
||||
PUSH_EVENT(SC_EVENT_DEMUXER_ERROR);
|
||||
|
@ -231,12 +234,14 @@ sc_video_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos,
|
|||
}
|
||||
|
||||
static void
|
||||
sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos,
|
||||
void *userdata) {
|
||||
sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer,
|
||||
enum sc_demuxer_status status, void *userdata) {
|
||||
(void) demuxer;
|
||||
(void) userdata;
|
||||
|
||||
// Contrary to the video demuxer, keep mirroring if only the audio fails.
|
||||
const struct scrcpy_options *options = userdata;
|
||||
|
||||
// Contrary to the video demuxer, keep mirroring if only the audio fails
|
||||
// (unless --require-audio is set).
|
||||
// 'eos' is true on end-of-stream, including when audio capture is not
|
||||
// possible on the device (so that scrcpy continue to mirror video without
|
||||
// failing).
|
||||
|
@ -244,7 +249,9 @@ sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer, bool eos,
|
|||
// explicitly selected an unknown audio encoder), 'eos' is false and scrcpy
|
||||
// must exit.
|
||||
|
||||
if (!eos) {
|
||||
if (status == SC_DEMUXER_STATUS_ERROR
|
||||
|| (status == SC_DEMUXER_STATUS_DISABLED
|
||||
&& options->require_audio)) {
|
||||
PUSH_EVENT(SC_EVENT_DEMUXER_ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -443,7 +450,7 @@ scrcpy(struct scrcpy_options *options) {
|
|||
.on_ended = sc_audio_demuxer_on_ended,
|
||||
};
|
||||
sc_demuxer_init(&s->audio_demuxer, "audio", s->server.audio_socket,
|
||||
&audio_demuxer_cbs, NULL);
|
||||
&audio_demuxer_cbs, options);
|
||||
}
|
||||
|
||||
bool needs_video_decoder = options->display;
|
||||
|
|
Loading…
Add table
Reference in a new issue