Compare commits

..

17 Commits

Author SHA1 Message Date
Romain Vimont
3c7a6d363e Disable default stdout/stderr for Xiaomi devices
Xiaomi device ROMs print internal errors using e.printStackTRace(),
flooding the console with irrelevant errors.

To get rid of them, on Xiaomi devices, trash the messages printed to the
console by direct calls to System.out and System.err.

Refs #994 <https://github.com/Genymobile/scrcpy/issues/994>
Refs #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
2023-11-01 00:35:42 +01:00
Romain Vimont
c64d150202 Improve manpage formatting 2023-10-31 19:20:59 +01:00
Romain Vimont
8350a61926 Simplify URLs in manpage
The .UR-formatted URLs are not always rendered correctly. Use simple
brackets instead.
2023-10-31 19:19:34 +01:00
Romain Vimont
5580803406 Always print device model and version
Print the log before checking for --list-* options so that it is
printed in all cases.
2023-10-31 19:19:33 +01:00
Romain Vimont
9bfc749803 Add camera documentation
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
2023-10-31 15:57:06 +01:00
Andrew Gunnerson
6af4bd601f Add support for high frame rate camera capture
Add --camera-high-speed to enable high frame rate camera capture. If
the option is enabled, then --camera-fps is mandatory.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-10-31 15:57:06 +01:00
Andrew Gunnerson
4722bff423 Add --camera-fps
Add a new option for specifying the camera frame rate.

By default, Android's default frame rate (30 fps) is used.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-10-31 15:57:06 +01:00
Romain Vimont
928f8b8eb3 Do not arbitrary limit --max-fps to 1000
Limit to the variable type size, for consistency.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
2023-10-31 15:57:06 +01:00
Simon Chan
9fc5835485 Fail-fast camera mirroring on Android 11 and older
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-10-31 15:57:06 +01:00
Romain Vimont
dd36d6135f Support camera size selection using -m/--camera-ar
In addition to --camera-size to specify an explicit size, make it
possible to select the camera size automatically, respecting the maximum
size (already used for display mirroring) and an aspect ratio.

For example, "scrcpy --video-source=camera" followed by:
 - (no additional arguments)
    : mirrors at the maximum size, any a-r
 - -m1920
    : only consider valid sizes having both dimensions not above 1920
 - --camera-ar=4:3
    : only consider valid sizes having an aspect ratio of 4:3 (+/- 10%)
 - -m2048 --camera-ar=1.6
    : only consider valid sizes having both dimensions not above 2048
      and an aspect ratio of 1.6 (+/- 10%)

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Co-authored-by: Simon Chan <1330321+yume-chan@users.noreply.github.com>
2023-10-31 15:57:06 +01:00
Simon Chan
faebb7d70a Add --camera-facing
Add an option to select the camera by its lens facing (front, back or
external).

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-10-31 15:57:06 +01:00
Romain Vimont
7f8d079c8c Make camera id optional
If no camera id is provided, use the first camera available.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
2023-10-31 15:57:06 +01:00
Romain Vimont
64930e71b9 Handle camera disconnection
Stop mirroring on camera disconnection.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
2023-10-31 15:57:06 +01:00
Romain Vimont
d544e577c0 Automatically select audio source
If --audio-source is not specified, select the default value
according to the video source:
 - for display mirroring, use device audio by default;
 - for camera mirroring, use microphone by default.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
2023-10-31 15:57:06 +01:00
Simon Chan
bfeecc0131 Add camera mirroring
Add --video-source=camera, and related options:
 - --camera-id=<id>: select the camera by its id (see --list-cameras);
 - --camera-size=<width>x<height>: select the capture size.

Fixed #241 <https://github.com/Genymobile/scrcpy/issues/241>
PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-10-31 15:57:06 +01:00
Romain Vimont
f032262cd7 Add --list-camera-sizes
Add an option to list the device camera declared sizes.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>
2023-10-31 15:57:06 +01:00
Simon Chan
cd63896d63 Add --list-cameras
Add an option to list the device cameras.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Co-authored-by: Romain Vimont <rom@rom1v.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
2023-10-31 15:56:25 +01:00
4 changed files with 111 additions and 44 deletions

View File

@@ -45,15 +45,15 @@ Set a list of comma-separated key:type=value options for the device audio encode
The possible values for 'type' are 'int' (default), 'long', 'float' and 'string'.
The list of possible codec options is available in the Android documentation
.UR https://d.android.com/reference/android/media/MediaFormat
.UE .
The list of possible codec options is available in the Android documentation:
<https://d.android.com/reference/android/media/MediaFormat>
.TP
.BI "\-\-audio\-encoder " name
Use a specific MediaCodec audio encoder (depending on the codec provided by \fB\-\-audio\-codec\fR).
The available encoders can be listed by \-\-list\-encoders.
The available encoders can be listed by \fB\-\-list\-encoders\fR.
.TP
.BI "\-\-audio\-source " source
@@ -79,19 +79,19 @@ Default is 8M (8000000).
.BI "\-\-camera\-ar " ar
Select the camera size by its aspect ratio (+/- 10%).
Possible values are "sensor" (use the camera sensor aspect ratio), "<num>:<den>" (e.g. "4:3") and "<value>" (e.g. "1.6").
Possible values are "sensor" (use the camera sensor aspect ratio), "\fInum\fR:\fIden\fR" (e.g. "4:3") and "\fIvalue\fR" (e.g. "1.6").
.TP
.B \-\-camera\-high\-speed
Enable high-speed camera capture mode.
This mode is restricted to specific resolutions and frame rates, listed by --list-camera-sizes.
This mode is restricted to specific resolutions and frame rates, listed by \fB\-\-list\-camera\-sizes\fR.
.TP
.BI "\-\-camera\-id " id
Specify the device camera id to mirror.
The available camera ids can be listed by \-\-list\-cameras.
The available camera ids can be listed by \fB\-\-list\-cameras\fR.
.TP
.BI "\-\-camera\-facing " facing
@@ -131,7 +131,7 @@ Disable screensaver while scrcpy is running.
.BI "\-\-display\-id " id
Specify the device display id to mirror.
The available display ids can be listed by \-\-list\-displays.
The available display ids can be listed by \fB\-\-list\-displays\fR.
Default is 0.
@@ -189,9 +189,11 @@ Inject computer clipboard text as a sequence of key events on Ctrl+v (like MOD+S
This is a workaround for some devices not behaving as expected when setting the device clipboard programmatically.
.TP
.B \-\-list\-camera\-sizes
List the valid camera capture sizes.
.TP
.B \-\-list\-cameras
List cameras available on the device.
@@ -239,7 +241,7 @@ Disable device control (mirror the device in read\-only).
.TP
.B \-N, \-\-no\-playback
Disable video and audio playback on the computer (equivalent to --no-video-playback --no-audio-playback).
Disable video and audio playback on the computer (equivalent to \fB\-\-no\-video\-playback \-\-no\-audio\-playback\fR).
.TP
.B \-\-no\-audio
@@ -361,8 +363,7 @@ Request SDL to use the given render driver (this is just a hint).
Supported names are currently "direct3d", "opengl", "opengles2", "opengles", "metal" and "software".
.UR https://wiki.libsdl.org/SDL_HINT_RENDER_DRIVER
.UE
<https://wiki.libsdl.org/SDL_HINT_RENDER_DRIVER>
.TP
.B \-\-require\-audio
@@ -410,13 +411,13 @@ Set the maximum mirroring time, in seconds.
.TP
.BI "\-\-tunnel\-host " ip
Set the IP address of the adb tunnel to reach the scrcpy server. This option automatically enables --force-adb-forward.
Set the IP address of the adb tunnel to reach the scrcpy server. This option automatically enables \fB\-\-force\-adb\-forward\fR.
Default is localhost.
.TP
.BI "\-\-tunnel\-port " port
Set the TCP port of the adb tunnel to reach the scrcpy server. This option automatically enables --force-adb-forward.
Set the TCP port of the adb tunnel to reach the scrcpy server. This option automatically enables \fB\-\-force\-adb\-forward\fR.
Default is 0 (not forced): the local port used for establishing the tunnel will be used.
@@ -456,15 +457,15 @@ Set a list of comma-separated key:type=value options for the device video encode
The possible values for 'type' are 'int' (default), 'long', 'float' and 'string'.
The list of possible codec options is available in the Android documentation
.UR https://d.android.com/reference/android/media/MediaFormat
.UE .
The list of possible codec options is available in the Android documentation:
<https://d.android.com/reference/android/media/MediaFormat>
.TP
.BI "\-\-video\-encoder " name
Use a specific MediaCodec video encoder (depending on the codec provided by \fB\-\-video\-codec\fR).
The available encoders can be listed by \-\-list\-encoders.
The available encoders can be listed by \fB\-\-list\-encoders\fR.
.TP
.BI "\-\-video\-source " source
@@ -634,7 +635,7 @@ Path to adb.
.TP
.B ANDROID_SERIAL
Device serial to use if no selector (-s, -d, -e or --tcpip=<addr>) is specified.
Device serial to use if no selector (\fB-s\fR, \fB-d\fR, \fB-e\fR or \fB\-\-tcpip=\fIaddr\fR) is specified.
.TP
.B SCRCPY_ICON_PATH
@@ -657,23 +658,14 @@ for the Debian Project (and may be used by others).
.SH "REPORTING BUGS"
Report bugs to
.UR https://github.com/Genymobile/scrcpy/issues
.UE .
Report bugs to <https://github.com/Genymobile/scrcpy/issues>.
.SH COPYRIGHT
Copyright \(co 2018 Genymobile
.UR https://www.genymobile.com
Genymobile
.UE
Copyright \(co 2018 Genymobile <https://www.genymobile.com>
Copyright \(co 2018\-2023
.MT rom@rom1v.com
Romain Vimont
.ME
Copyright \(co 2018\-2023 Romain Vimont <rom@rom1v.com>
Licensed under the Apache License, Version 2.0.
.SH WWW
.UR https://github.com/Genymobile/scrcpy
.UE
<https://github.com/Genymobile/scrcpy>

View File

@@ -8,6 +8,11 @@ import android.util.Log;
*/
public final class Ln {
public interface ConsolePrinter {
void printOut(String message);
void printErr(String message, Throwable throwable);
}
private static final String TAG = "scrcpy";
private static final String PREFIX = "[server] ";
@@ -15,12 +20,17 @@ public final class Ln {
VERBOSE, DEBUG, INFO, WARN, ERROR
}
private static ConsolePrinter consolePrinter = new DefaultConsolePrinter();
private static Level threshold = Level.INFO;
private Ln() {
// not instantiable
}
public static void setConsolePrinter(ConsolePrinter consolePrinter) {
Ln.consolePrinter = consolePrinter;
}
/**
* Initialize the log level.
* <p>
@@ -39,31 +49,28 @@ public final class Ln {
public static void v(String message) {
if (isEnabled(Level.VERBOSE)) {
Log.v(TAG, message);
System.out.print(PREFIX + "VERBOSE: " + message + '\n');
consolePrinter.printOut(PREFIX + "VERBOSE: " + message + '\n');
}
}
public static void d(String message) {
if (isEnabled(Level.DEBUG)) {
Log.d(TAG, message);
System.out.print(PREFIX + "DEBUG: " + message + '\n');
consolePrinter.printOut(PREFIX + "DEBUG: " + message + '\n');
}
}
public static void i(String message) {
if (isEnabled(Level.INFO)) {
Log.i(TAG, message);
System.out.print(PREFIX + "INFO: " + message + '\n');
consolePrinter.printOut(PREFIX + "INFO: " + message + '\n');
}
}
public static void w(String message, Throwable throwable) {
if (isEnabled(Level.WARN)) {
Log.w(TAG, message, throwable);
System.err.print(PREFIX + "WARN: " + message + '\n');
if (throwable != null) {
throwable.printStackTrace();
}
consolePrinter.printErr(PREFIX + "WARN: " + message + '\n', throwable);
}
}
@@ -74,14 +81,26 @@ public final class Ln {
public static void e(String message, Throwable throwable) {
if (isEnabled(Level.ERROR)) {
Log.e(TAG, message, throwable);
System.err.print(PREFIX + "ERROR: " + message + "\n");
if (throwable != null) {
throwable.printStackTrace();
}
consolePrinter.printErr(PREFIX + "ERROR: " + message + '\n', throwable);
}
}
public static void e(String message) {
e(message, null);
}
public static class DefaultConsolePrinter implements ConsolePrinter {
@Override
public void printOut(String message) {
System.out.print(message);
}
@Override
public void printErr(String message, Throwable throwable) {
System.err.print(message);
if (throwable != null) {
throwable.printStackTrace();
}
}
}
}

View File

@@ -87,8 +87,6 @@ public final class Server {
}
private static void scrcpy(Options options) throws IOException, ConfigurationException {
Ln.i("Device: [" + Build.MANUFACTURER + "] " + Build.BRAND + " " + Build.MODEL + " (Android " + Build.VERSION.RELEASE + ")");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S && options.getVideoSource() == VideoSource.CAMERA) {
Ln.e("Camera mirroring is not supported before Android 12");
throw new ConfigurationException("Camera mirroring is not supported");
@@ -208,6 +206,8 @@ public final class Server {
Ln.initLogLevel(options.getLogLevel());
Ln.i("Device: [" + Build.MANUFACTURER + "] " + Build.BRAND + " " + Build.MODEL + " (Android " + Build.VERSION.RELEASE + ")");
if (options.getList()) {
if (options.getCleanup()) {
CleanUp.unlinkSelf();

View File

@@ -14,6 +14,12 @@ import android.os.Build;
import android.os.Looper;
import android.os.Parcel;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -55,6 +61,12 @@ public final class Workarounds {
mustFillAppInfo = true;
mustFillBaseContext = true;
mustFillAppContext = true;
} else if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) {
// Trash the messages printed to the console by direct calls to System.out and System.err.
// Xiaomi device ROMs may print internal errors using e.printStackTrace(), flooding the console with irrelevant errors.
ExclusiveConsolePrinter exclusiveConsolePrinter = new ExclusiveConsolePrinter();
exclusiveConsolePrinter.installNullSystemStreams();
Ln.setConsolePrinter(new ExclusiveConsolePrinter());
}
if (audio && Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
@@ -306,4 +318,48 @@ public final class Workarounds {
throw new RuntimeException("Cannot create AudioRecord");
}
}
static class ExclusiveConsolePrinter implements Ln.ConsolePrinter {
static class NullOutputStream extends OutputStream {
@Override
public void write(byte[] b) {
// ignore
}
@Override
public void write(byte[] b, int off, int len) {
// ignore
}
@Override
public void write(int b) {
// ignore
}
}
private final PrintStream realOut = new PrintStream(new FileOutputStream(FileDescriptor.out));
private final PrintStream realErr = new PrintStream(new FileOutputStream(FileDescriptor.err));
void installNullSystemStreams() {
PrintStream nullStream = new PrintStream(new NullOutputStream());
System.setOut(nullStream);
System.setErr(nullStream);
}
@Override
public void printOut(String message) {
realOut.print(message);
}
@Override
public void printErr(String message, Throwable throwable) {
realErr.print(message);
if (throwable != null) {
StringWriter errors = new StringWriter();
throwable.printStackTrace(new PrintWriter(errors));
realErr.print(errors);
}
}
}
}