Compare commits
1 Commits
pause_on_e
...
doc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d25f38266d |
@@ -5,7 +5,7 @@
|
|||||||
_pronounced "**scr**een **c**o**py**"_
|
_pronounced "**scr**een **c**o**py**"_
|
||||||
|
|
||||||
This application mirrors Android devices (video and audio) connected via
|
This application mirrors Android devices (video and audio) connected via
|
||||||
USB or [over TCP/IP](doc/connection.md#tcpip-wireless), and allows to control the
|
USB or [over TCP/IP](doc/device.md#tcpip-wireless), and allows to control the
|
||||||
device with the keyboard and the mouse of the computer. It does not require any
|
device with the keyboard and the mouse of the computer. It does not require any
|
||||||
_root_ access. It works on _Linux_, _Windows_ and _macOS_.
|
_root_ access. It works on _Linux_, _Windows_ and _macOS_.
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ _scrcpy() {
|
|||||||
--no-video-playback
|
--no-video-playback
|
||||||
--otg
|
--otg
|
||||||
-p --port=
|
-p --port=
|
||||||
--pause-on-exit
|
|
||||||
--pause-on-exit=
|
|
||||||
--power-off-on-close
|
--power-off-on-close
|
||||||
--prefer-text
|
--prefer-text
|
||||||
--print-fps
|
--print-fps
|
||||||
@@ -99,10 +97,6 @@ _scrcpy() {
|
|||||||
COMPREPLY=($(compgen -W 'unlocked initial 0 1 2 3' -- "$cur"))
|
COMPREPLY=($(compgen -W 'unlocked initial 0 1 2 3' -- "$cur"))
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--pause-on-exit)
|
|
||||||
COMPREPLY=($(compgen -W 'true false if-error' -- "$cur"))
|
|
||||||
return
|
|
||||||
;;
|
|
||||||
-r|--record)
|
-r|--record)
|
||||||
COMPREPLY=($(compgen -f -- "$cur"))
|
COMPREPLY=($(compgen -f -- "$cur"))
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
@echo off
|
@echo off
|
||||||
scrcpy.exe --pause-on-exit=if-error %*
|
scrcpy.exe %*
|
||||||
|
:: if the exit code is >= 1, then pause
|
||||||
|
if errorlevel 1 pause
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Comment=Display and control your Android device
|
|||||||
# For some users, the PATH or ADB environment variables are set from the shell
|
# For some users, the PATH or ADB environment variables are set from the shell
|
||||||
# startup file, like .bashrc or .zshrc… Run an interactive shell to get
|
# startup file, like .bashrc or .zshrc… Run an interactive shell to get
|
||||||
# environment correctly initialized.
|
# environment correctly initialized.
|
||||||
Exec=/bin/sh -c "\"\\$SHELL\" -i -c scrcpy --pause-on-exit=if-error"
|
Exec=/bin/bash --norc --noprofile -i -c "\"\\$SHELL\" -i -c scrcpy || read -p 'Press Enter to quit...'"
|
||||||
Icon=scrcpy
|
Icon=scrcpy
|
||||||
Terminal=true
|
Terminal=true
|
||||||
Type=Application
|
Type=Application
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ arguments=(
|
|||||||
'--no-video-playback[Disable video playback]'
|
'--no-video-playback[Disable video playback]'
|
||||||
'--otg[Run in OTG mode \(simulating physical keyboard and mouse\)]'
|
'--otg[Run in OTG mode \(simulating physical keyboard and mouse\)]'
|
||||||
{-p,--port=}'[\[port\[\:port\]\] Set the TCP port \(range\) used by the client to listen]'
|
{-p,--port=}'[\[port\[\:port\]\] Set the TCP port \(range\) used by the client to listen]'
|
||||||
'--pause-on-exit=[Make scrcpy pause before exiting]:mode:(true false if-error)'
|
|
||||||
'--power-off-on-close[Turn the device screen off when closing scrcpy]'
|
'--power-off-on-close[Turn the device screen off when closing scrcpy]'
|
||||||
'--prefer-text[Inject alpha characters and space as text events instead of key events]'
|
'--prefer-text[Inject alpha characters and space as text events instead of key events]'
|
||||||
'--print-fps[Start FPS counter, to print frame logs to the console]'
|
'--print-fps[Start FPS counter, to print frame logs to the console]'
|
||||||
|
|||||||
10
app/scrcpy.1
10
app/scrcpy.1
@@ -267,16 +267,6 @@ Set the TCP port (range) used by the client to listen.
|
|||||||
|
|
||||||
Default is 27183:27199.
|
Default is 27183:27199.
|
||||||
|
|
||||||
.TP
|
|
||||||
\fB\-\-pause\-on\-exit\fR[=\fImode\fR]
|
|
||||||
Configure pause on exit. Possible values are "true" (always pause on exit), "false" (never pause on exit) and "if-error" (pause only if an error occured).
|
|
||||||
|
|
||||||
This is useful to prevent the terminal window from automatically closing, so that error messages can be read.
|
|
||||||
|
|
||||||
Default is "false".
|
|
||||||
|
|
||||||
Passing the option without argument is equivalent to passing "true".
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-\-power\-off\-on\-close
|
.B \-\-power\-off\-on\-close
|
||||||
Turn the device screen off when closing scrcpy.
|
Turn the device screen off when closing scrcpy.
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ enum {
|
|||||||
OPT_AUDIO_SOURCE,
|
OPT_AUDIO_SOURCE,
|
||||||
OPT_KILL_ADB_ON_CLOSE,
|
OPT_KILL_ADB_ON_CLOSE,
|
||||||
OPT_TIME_LIMIT,
|
OPT_TIME_LIMIT,
|
||||||
OPT_PAUSE_ON_EXIT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_option {
|
struct sc_option {
|
||||||
@@ -464,20 +463,6 @@ static const struct sc_option options[] = {
|
|||||||
"Default is " STR(DEFAULT_LOCAL_PORT_RANGE_FIRST) ":"
|
"Default is " STR(DEFAULT_LOCAL_PORT_RANGE_FIRST) ":"
|
||||||
STR(DEFAULT_LOCAL_PORT_RANGE_LAST) ".",
|
STR(DEFAULT_LOCAL_PORT_RANGE_LAST) ".",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.longopt_id = OPT_PAUSE_ON_EXIT,
|
|
||||||
.longopt = "pause-on-exit",
|
|
||||||
.argdesc = "mode",
|
|
||||||
.optional_arg = true,
|
|
||||||
.text = "Configure pause on exit. Possible values are \"true\" (always "
|
|
||||||
"pause on exit), \"false\" (never pause on exit) and "
|
|
||||||
"\"if-error\" (pause only if an error occured).\n"
|
|
||||||
"This is useful to prevent the terminal window from "
|
|
||||||
"automatically closing, so that error messages can be read.\n"
|
|
||||||
"Default is \"false\".\n"
|
|
||||||
"Passing the option without argument is equivalent to passing "
|
|
||||||
"\"true\".",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.longopt_id = OPT_POWER_OFF_ON_CLOSE,
|
.longopt_id = OPT_POWER_OFF_ON_CLOSE,
|
||||||
.longopt = "power-off-on-close",
|
.longopt = "power-off-on-close",
|
||||||
@@ -1652,29 +1637,6 @@ parse_time_limit(const char *s, sc_tick *tick) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
parse_pause_on_exit(const char *s, enum sc_pause_on_exit *pause_on_exit) {
|
|
||||||
if (!s || !strcmp(s, "true")) {
|
|
||||||
*pause_on_exit = SC_PAUSE_ON_EXIT_TRUE;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(s, "false")) {
|
|
||||||
*pause_on_exit = SC_PAUSE_ON_EXIT_FALSE;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(s, "if-error")) {
|
|
||||||
*pause_on_exit = SC_PAUSE_ON_EXIT_IF_ERROR;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGE("Unsupported pause on exit mode: %s "
|
|
||||||
"(expected true, false or if-error)", optarg);
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
||||||
const char *optstring, const struct option *longopts) {
|
const char *optstring, const struct option *longopts) {
|
||||||
@@ -2015,11 +1977,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_PAUSE_ON_EXIT:
|
|
||||||
if (!parse_pause_on_exit(optarg, &args->pause_on_exit)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
// getopt prints the error message on stderr
|
// getopt prints the error message on stderr
|
||||||
return false;
|
return false;
|
||||||
@@ -2065,6 +2022,12 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
opts->audio_playback = false;
|
opts->audio_playback = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!opts->video_playback && !otg) {
|
||||||
|
// If video playback is disabled and OTG are disabled, then there is
|
||||||
|
// no way to control the device.
|
||||||
|
opts->control = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (opts->video && !opts->video_playback && !opts->record_filename
|
if (opts->video && !opts->video_playback && !opts->record_filename
|
||||||
&& !v4l2) {
|
&& !v4l2) {
|
||||||
LOGI("No video playback, no recording, no V4L2 sink: video disabled");
|
LOGI("No video playback, no recording, no V4L2 sink: video disabled");
|
||||||
@@ -2233,37 +2196,6 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum sc_pause_on_exit
|
|
||||||
sc_get_pause_on_exit(int argc, char *argv[]) {
|
|
||||||
// Read arguments backwards so that the last --pause-on-exit is considered
|
|
||||||
// (same behavior as getopt())
|
|
||||||
for (int i = argc - 1; i >= 1; --i) {
|
|
||||||
const char *arg = argv[i];
|
|
||||||
// Starts with "--pause-on-exit"
|
|
||||||
if (!strncmp("--pause-on-exit", arg, 15)) {
|
|
||||||
if (arg[15] == '\0') {
|
|
||||||
// No argument
|
|
||||||
return SC_PAUSE_ON_EXIT_TRUE;
|
|
||||||
}
|
|
||||||
if (arg[15] != '=') {
|
|
||||||
// Invalid parameter, ignore
|
|
||||||
return SC_PAUSE_ON_EXIT_FALSE;
|
|
||||||
}
|
|
||||||
const char *value = &arg[16];
|
|
||||||
if (!strcmp(value, "true")) {
|
|
||||||
return SC_PAUSE_ON_EXIT_TRUE;
|
|
||||||
}
|
|
||||||
if (!strcmp(value, "if-error")) {
|
|
||||||
return SC_PAUSE_ON_EXIT_IF_ERROR;
|
|
||||||
}
|
|
||||||
// Set to false, inclusing when the value is invalid
|
|
||||||
return SC_PAUSE_ON_EXIT_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||||
struct sc_getopt_adapter adapter;
|
struct sc_getopt_adapter adapter;
|
||||||
@@ -2277,11 +2209,5 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
|||||||
|
|
||||||
sc_getopt_adapter_destroy(&adapter);
|
sc_getopt_adapter_destroy(&adapter);
|
||||||
|
|
||||||
if (!ret && args->pause_on_exit == SC_PAUSE_ON_EXIT_FALSE) {
|
|
||||||
// Check if "--pause-on-exit" is present in the arguments list, because
|
|
||||||
// it must be taken into account even if command line parsing failed
|
|
||||||
args->pause_on_exit = sc_get_pause_on_exit(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,10 @@
|
|||||||
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
enum sc_pause_on_exit {
|
|
||||||
SC_PAUSE_ON_EXIT_TRUE,
|
|
||||||
SC_PAUSE_ON_EXIT_FALSE,
|
|
||||||
SC_PAUSE_ON_EXIT_IF_ERROR,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct scrcpy_cli_args {
|
struct scrcpy_cli_args {
|
||||||
struct scrcpy_options opts;
|
struct scrcpy_options opts;
|
||||||
bool help;
|
bool help;
|
||||||
bool version;
|
bool version;
|
||||||
enum sc_pause_on_exit pause_on_exit;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ sc_display_init(struct sc_display *display, SDL_Window *window, bool mipmaps) {
|
|||||||
display->mipmaps = true;
|
display->mipmaps = true;
|
||||||
} else {
|
} else {
|
||||||
LOGW("Trilinear filtering disabled "
|
LOGW("Trilinear filtering disabled "
|
||||||
"(OpenGL 3.0+ or ES 2.0+ required)");
|
"(OpenGL 3.0+ or ES 2.0+ required");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGI("Trilinear filtering disabled");
|
LOGI("Trilinear filtering disabled");
|
||||||
|
|||||||
@@ -39,32 +39,26 @@ main_scrcpy(int argc, char *argv[]) {
|
|||||||
.opts = scrcpy_options_default,
|
.opts = scrcpy_options_default,
|
||||||
.help = false,
|
.help = false,
|
||||||
.version = false,
|
.version = false,
|
||||||
.pause_on_exit = SC_PAUSE_ON_EXIT_FALSE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
args.opts.log_level = SC_LOG_LEVEL_DEBUG;
|
args.opts.log_level = SC_LOG_LEVEL_DEBUG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum scrcpy_exit_code ret;
|
|
||||||
|
|
||||||
if (!scrcpy_parse_args(&args, argc, argv)) {
|
if (!scrcpy_parse_args(&args, argc, argv)) {
|
||||||
ret = SCRCPY_EXIT_FAILURE;
|
return SCRCPY_EXIT_FAILURE;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_set_log_level(args.opts.log_level);
|
sc_set_log_level(args.opts.log_level);
|
||||||
|
|
||||||
if (args.help) {
|
if (args.help) {
|
||||||
scrcpy_print_usage(argv[0]);
|
scrcpy_print_usage(argv[0]);
|
||||||
ret = SCRCPY_EXIT_SUCCESS;
|
return SCRCPY_EXIT_SUCCESS;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.version) {
|
if (args.version) {
|
||||||
scrcpy_print_version();
|
scrcpy_print_version();
|
||||||
ret = SCRCPY_EXIT_SUCCESS;
|
return SCRCPY_EXIT_SUCCESS;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SCRCPY_LAVF_REQUIRES_REGISTER_ALL
|
#ifdef SCRCPY_LAVF_REQUIRES_REGISTER_ALL
|
||||||
@@ -78,26 +72,18 @@ main_scrcpy(int argc, char *argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!net_init()) {
|
if (!net_init()) {
|
||||||
ret = SCRCPY_EXIT_FAILURE;
|
return SCRCPY_EXIT_FAILURE;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_log_configure();
|
sc_log_configure();
|
||||||
|
|
||||||
#ifdef HAVE_USB
|
#ifdef HAVE_USB
|
||||||
ret = args.opts.otg ? scrcpy_otg(&args.opts) : scrcpy(&args.opts);
|
enum scrcpy_exit_code ret = args.opts.otg ? scrcpy_otg(&args.opts)
|
||||||
|
: scrcpy(&args.opts);
|
||||||
#else
|
#else
|
||||||
ret = scrcpy(&args.opts);
|
enum scrcpy_exit_code ret = scrcpy(&args.opts);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
end:
|
|
||||||
if (args.pause_on_exit == SC_PAUSE_ON_EXIT_TRUE ||
|
|
||||||
(args.pause_on_exit == SC_PAUSE_ON_EXIT_IF_ERROR &&
|
|
||||||
ret != SCRCPY_EXIT_SUCCESS)) {
|
|
||||||
printf("Press Enter to continue...\n");
|
|
||||||
getchar();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -252,9 +252,7 @@ sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer,
|
|||||||
|
|
||||||
// Contrary to the video demuxer, keep mirroring if only the audio fails
|
// Contrary to the video demuxer, keep mirroring if only the audio fails
|
||||||
// (unless --require-audio is set).
|
// (unless --require-audio is set).
|
||||||
if (status == SC_DEMUXER_STATUS_EOS) {
|
if (status == SC_DEMUXER_STATUS_ERROR
|
||||||
PUSH_EVENT(SC_EVENT_DEVICE_DISCONNECTED);
|
|
||||||
} else if (status == SC_DEMUXER_STATUS_ERROR
|
|
||||||
|| (status == SC_DEMUXER_STATUS_DISABLED
|
|| (status == SC_DEMUXER_STATUS_DISABLED
|
||||||
&& options->require_audio)) {
|
&& options->require_audio)) {
|
||||||
PUSH_EVENT(SC_EVENT_DEMUXER_ERROR);
|
PUSH_EVENT(SC_EVENT_DEMUXER_ERROR);
|
||||||
@@ -450,7 +448,9 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
|
|
||||||
struct sc_file_pusher *fp = NULL;
|
struct sc_file_pusher *fp = NULL;
|
||||||
|
|
||||||
if (options->video_playback && options->control) {
|
// control implies video playback
|
||||||
|
assert(!options->control || options->video_playback);
|
||||||
|
if (options->control) {
|
||||||
if (!sc_file_pusher_init(&s->file_pusher, serial,
|
if (!sc_file_pusher_init(&s->file_pusher, serial,
|
||||||
options->push_target)) {
|
options->push_target)) {
|
||||||
goto end;
|
goto end;
|
||||||
|
|||||||
14
doc/audio.md
14
doc/audio.md
@@ -77,13 +77,6 @@ In particular, if you get the following error:
|
|||||||
|
|
||||||
then your device has no Opus encoder: try `scrcpy --audio-codec=aac`.
|
then your device has no Opus encoder: try `scrcpy --audio-codec=aac`.
|
||||||
|
|
||||||
For advanced usage, to pass arbitrary parameters to the [`MediaFormat`],
|
|
||||||
check `--audio-codec-options` in the manpage or in `scrcpy --help`.
|
|
||||||
|
|
||||||
[`MediaFormat`]: https://developer.android.com/reference/android/media/MediaFormat
|
|
||||||
|
|
||||||
|
|
||||||
## Encoder
|
|
||||||
|
|
||||||
Several encoders may be available on the device. They can be listed by:
|
Several encoders may be available on the device. They can be listed by:
|
||||||
|
|
||||||
@@ -93,10 +86,15 @@ scrcpy --list-encoders
|
|||||||
|
|
||||||
To select a specific encoder:
|
To select a specific encoder:
|
||||||
|
|
||||||
```bash
|
```
|
||||||
scrcpy --audio-codec=opus --audio-encoder='c2.android.opus.encoder'
|
scrcpy --audio-codec=opus --audio-encoder='c2.android.opus.encoder'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For advanced usage, to pass arbitrary parameters to the [`MediaFormat`],
|
||||||
|
check `--audio-codec-options` in the manpage or in `scrcpy --help`.
|
||||||
|
|
||||||
|
[`MediaFormat`]: https://developer.android.com/reference/android/media/MediaFormat
|
||||||
|
|
||||||
|
|
||||||
## Bit rate
|
## Bit rate
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,23 @@
|
|||||||
# Device
|
# Device
|
||||||
|
|
||||||
Some command line arguments perform actions on the device itself while scrcpy is
|
## Display
|
||||||
running.
|
|
||||||
|
If several displays are available on the Android device, it is possible to
|
||||||
|
select the display to mirror:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scrcpy --display=1
|
||||||
|
```
|
||||||
|
|
||||||
|
The list of display ids can be retrieved by:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scrcpy --list-displays
|
||||||
|
```
|
||||||
|
|
||||||
|
A secondary display may only be controlled if the device runs at least Android
|
||||||
|
10 (otherwise it is mirrored as read-only).
|
||||||
|
|
||||||
|
|
||||||
## Stay awake
|
## Stay awake
|
||||||
|
|
||||||
@@ -78,3 +94,4 @@ By default, on start, the device is powered on. To prevent this behavior:
|
|||||||
```bash
|
```bash
|
||||||
scrcpy --no-power-on
|
scrcpy --no-power-on
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
32
doc/video.md
32
doc/video.md
@@ -66,14 +66,6 @@ scrcpy --video-codec=av1
|
|||||||
H265 may provide better quality, but H264 should provide lower latency.
|
H265 may provide better quality, but H264 should provide lower latency.
|
||||||
AV1 encoders are not common on current Android devices.
|
AV1 encoders are not common on current Android devices.
|
||||||
|
|
||||||
For advanced usage, to pass arbitrary parameters to the [`MediaFormat`],
|
|
||||||
check `--video-codec-options` in the manpage or in `scrcpy --help`.
|
|
||||||
|
|
||||||
[`MediaFormat`]: https://developer.android.com/reference/android/media/MediaFormat
|
|
||||||
|
|
||||||
|
|
||||||
## Encoder
|
|
||||||
|
|
||||||
Several encoders may be available on the device. They can be listed by:
|
Several encoders may be available on the device. They can be listed by:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -87,6 +79,11 @@ try another one:
|
|||||||
scrcpy --video-codec=h264 --video-encoder='OMX.qcom.video.encoder.avc'
|
scrcpy --video-codec=h264 --video-encoder='OMX.qcom.video.encoder.avc'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For advanced usage, to pass arbitrary parameters to the [`MediaFormat`],
|
||||||
|
check `--video-codec-options` in the manpage or in `scrcpy --help`.
|
||||||
|
|
||||||
|
[`MediaFormat`]: https://developer.android.com/reference/android/media/MediaFormat
|
||||||
|
|
||||||
|
|
||||||
## Rotation
|
## Rotation
|
||||||
|
|
||||||
@@ -137,25 +134,6 @@ phone, landscape for a tablet).
|
|||||||
If `--max-size` is also specified, resizing is applied after cropping.
|
If `--max-size` is also specified, resizing is applied after cropping.
|
||||||
|
|
||||||
|
|
||||||
## Display
|
|
||||||
|
|
||||||
If several displays are available on the Android device, it is possible to
|
|
||||||
select the display to mirror:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scrcpy --display=1
|
|
||||||
```
|
|
||||||
|
|
||||||
The list of display ids can be retrieved by:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scrcpy --list-displays
|
|
||||||
```
|
|
||||||
|
|
||||||
A secondary display may only be controlled if the device runs at least Android
|
|
||||||
10 (otherwise it is mirrored as read-only).
|
|
||||||
|
|
||||||
|
|
||||||
## Buffering
|
## Buffering
|
||||||
|
|
||||||
By default, there is no video buffering, to get the lowest possible latency.
|
By default, there is no video buffering, to get the lowest possible latency.
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public final class Workarounds {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void fillBaseContext() {
|
public static void fillBaseContext() {
|
||||||
try {
|
try {
|
||||||
fillActivityThread();
|
fillActivityThread();
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@SuppressLint("PrivateApi,DiscouragedPrivateApi")
|
@SuppressLint("PrivateApi,DiscouragedPrivateApi")
|
||||||
public final class ActivityManager {
|
public class ActivityManager {
|
||||||
|
|
||||||
private final IInterface manager;
|
private final IInterface manager;
|
||||||
private Method getContentProviderExternalMethod;
|
private Method getContentProviderExternalMethod;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import android.os.IInterface;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public final class ClipboardManager {
|
public class ClipboardManager {
|
||||||
private final IInterface manager;
|
private final IInterface manager;
|
||||||
private Method getPrimaryClipMethod;
|
private Method getPrimaryClipMethod;
|
||||||
private Method setPrimaryClipMethod;
|
private Method setPrimaryClipMethod;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.io.Closeable;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public final class ContentProvider implements Closeable {
|
public class ContentProvider implements Closeable {
|
||||||
|
|
||||||
public static final String TABLE_SYSTEM = "system";
|
public static final String TABLE_SYSTEM = "system";
|
||||||
public static final String TABLE_SECURE = "secure";
|
public static final String TABLE_SECURE = "secure";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import android.os.IInterface;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
public final class StatusBarManager {
|
public class StatusBarManager {
|
||||||
|
|
||||||
private final IInterface manager;
|
private final IInterface manager;
|
||||||
private Method expandNotificationsPanelMethod;
|
private Method expandNotificationsPanelMethod;
|
||||||
|
|||||||
Reference in New Issue
Block a user