Compare commits
16 Commits
turnscreen
...
release
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6ff78f414 | ||
|
|
40f2560d98 | ||
|
|
26aa28c998 | ||
|
|
ef79fcbbd2 | ||
|
|
9497f39fb4 | ||
|
|
bf056b1fee | ||
|
|
bd9292931e | ||
|
|
140a49b8be | ||
|
|
4135c411af | ||
|
|
5e061636f6 | ||
|
|
5f3fb843f5 | ||
|
|
ce8126f322 | ||
|
|
d037b02cc2 | ||
|
|
89761213c3 | ||
|
|
8db4e78b34 | ||
|
|
25e33566f5 |
@@ -1,4 +1,4 @@
|
|||||||
# scrcpy (v2.2)
|
# scrcpy (v2.3.1)
|
||||||
|
|
||||||
<img src="app/data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />
|
<img src="app/data/icon.svg" width="128" height="128" alt="scrcpy" align="right" />
|
||||||
|
|
||||||
|
|||||||
@@ -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/sh -c "\\$SHELL -i -c 'scrcpy --pause-on-exit=if-error'"
|
||||||
Icon=scrcpy
|
Icon=scrcpy
|
||||||
Terminal=true
|
Terminal=true
|
||||||
Type=Application
|
Type=Application
|
||||||
|
|||||||
@@ -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"
|
Exec=/bin/sh -c "\\$SHELL -i -c scrcpy"
|
||||||
Icon=scrcpy
|
Icon=scrcpy
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ BEGIN
|
|||||||
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
|
VALUE "LegalCopyright", "Romain Vimont, Genymobile"
|
||||||
VALUE "OriginalFilename", "scrcpy.exe"
|
VALUE "OriginalFilename", "scrcpy.exe"
|
||||||
VALUE "ProductName", "scrcpy"
|
VALUE "ProductName", "scrcpy"
|
||||||
VALUE "ProductVersion", "v2.2"
|
VALUE "ProductVersion", "2.3.1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@@ -2154,7 +2154,7 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_ORIENTATION:
|
case OPT_ORIENTATION: {
|
||||||
enum sc_orientation orientation;
|
enum sc_orientation orientation;
|
||||||
if (!parse_orientation(optarg, &orientation)) {
|
if (!parse_orientation(optarg, &orientation)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2162,6 +2162,7 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
|
|||||||
opts->display_orientation = orientation;
|
opts->display_orientation = orientation;
|
||||||
opts->record_orientation = orientation;
|
opts->record_orientation = orientation;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case OPT_RENDER_DRIVER:
|
case OPT_RENDER_DRIVER:
|
||||||
opts->render_driver = optarg;
|
opts->render_driver = optarg;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -227,8 +227,9 @@ run_demuxer(void *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Config packets must be merged with the next non-config packet only for
|
// Config packets must be merged with the next non-config packet only for
|
||||||
// video streams
|
// H.26x
|
||||||
bool must_merge_config_packet = codec->type == AVMEDIA_TYPE_VIDEO;
|
bool must_merge_config_packet = raw_codec_id == SC_CODEC_ID_H264
|
||||||
|
|| raw_codec_id == SC_CODEC_ID_H265;
|
||||||
|
|
||||||
struct sc_packet_merger merger;
|
struct sc_packet_merger merger;
|
||||||
|
|
||||||
|
|||||||
@@ -419,12 +419,21 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
sdl_set_hints(options->render_driver);
|
sdl_set_hints(options->render_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the video subsystem even if --no-video or --no-video-playback
|
if (options->video_playback ||
|
||||||
// is passed so that clipboard synchronization still works.
|
(options->control && options->clipboard_autosync)) {
|
||||||
// <https://github.com/Genymobile/scrcpy/issues/4418>
|
// Initialize the video subsystem even if --no-video or
|
||||||
if (SDL_Init(SDL_INIT_VIDEO)) {
|
// --no-video-playback is passed so that clipboard synchronization
|
||||||
LOGE("Could not initialize SDL video: %s", SDL_GetError());
|
// still works.
|
||||||
goto end;
|
// <https://github.com/Genymobile/scrcpy/issues/4418>
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
|
// If it fails, it is an error only if video playback is enabled
|
||||||
|
if (options->video_playback) {
|
||||||
|
LOGE("Could not initialize SDL video: %s", SDL_GetError());
|
||||||
|
goto end;
|
||||||
|
} else {
|
||||||
|
LOGW("Could not initialize SDL video: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->audio_playback) {
|
if (options->audio_playback) {
|
||||||
|
|||||||
@@ -233,10 +233,10 @@ install` must be run as root)._
|
|||||||
|
|
||||||
#### Option 2: Use prebuilt server
|
#### Option 2: Use prebuilt server
|
||||||
|
|
||||||
- [`scrcpy-server-v2.2`][direct-scrcpy-server]
|
- [`scrcpy-server-v2.3.1`][direct-scrcpy-server]
|
||||||
<sub>SHA-256: `c85c4aa84305efb69115cd497a120ebdd10258993b4cf123a8245b3d99d49874`</sub>
|
<sub>SHA-256: `f6814822fc308a7a532f253485c9038183c6296a6c5df470a9e383b4f8e7605b`</sub>
|
||||||
|
|
||||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v2.2/scrcpy-server-v2.2
|
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-server-v2.3.1
|
||||||
|
|
||||||
Download the prebuilt server somewhere, and specify its path during the Meson
|
Download the prebuilt server somewhere, and specify its path during the Meson
|
||||||
configuration:
|
configuration:
|
||||||
|
|||||||
@@ -18,6 +18,17 @@ scrcpy --video-source=display --audio-source=mic # force display AND micropho
|
|||||||
scrcpy --video-source=camera --audio-source=output # force camera AND device audio output
|
scrcpy --video-source=camera --audio-source=output # force camera AND device audio output
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Audio can be disabled:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# audio not captured at all
|
||||||
|
scrcpy --video-source=camera --no-audio
|
||||||
|
scrcpy --video-source=camera --no-audio --record=file.mp4
|
||||||
|
|
||||||
|
# audio captured and recorded, but not played
|
||||||
|
scrcpy --video-source=camera --no-audio-playback --record=file.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## List
|
## List
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ This will create a new video device in `/dev/videoN`, where `N` is an integer
|
|||||||
(more [options](https://github.com/umlaeute/v4l2loopback#options) are available
|
(more [options](https://github.com/umlaeute/v4l2loopback#options) are available
|
||||||
to create several devices or devices with specific IDs).
|
to create several devices or devices with specific IDs).
|
||||||
|
|
||||||
|
If you encounter problems detecting your device with Chrome/WebRTC, you can try
|
||||||
|
`exclusive_caps` mode:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo modprobe v4l2loopback exclusive_caps=1
|
||||||
|
```
|
||||||
|
|
||||||
To list the enabled devices:
|
To list the enabled devices:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
Download the [latest release]:
|
Download the [latest release]:
|
||||||
|
|
||||||
- [`scrcpy-win64-v2.2.zip`][direct-win64] (64-bit)
|
- [`scrcpy-win64-v2.3.1.zip`][direct-win64] (64-bit)
|
||||||
<sub>SHA-256: `9f9da88ac4c8319dcb9bf852f2d9bba942bac663413383419cddf64eaa5685bd`</sub>
|
<sub>SHA-256: `f1f78ac98214078425804e524a1bed515b9d4b8a05b78d210a4ced2b910b262d`</sub>
|
||||||
- [`scrcpy-win32-v2.2.zip`][direct-win32] (32-bit)
|
- [`scrcpy-win32-v2.3.1.zip`][direct-win32] (32-bit)
|
||||||
<sub>SHA-256: `cb84269fc847b8b880e320879492a1ae6c017b42175f03e199530f7a53be9d74`</sub>
|
<sub>SHA-256: `5dffc2d432e9b8b5b0e16f12e71428c37c70d9124cfbe7620df0b41b7efe91ff`</sub>
|
||||||
|
|
||||||
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
[latest release]: https://github.com/Genymobile/scrcpy/releases/latest
|
||||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v2.2/scrcpy-win64-v2.2.zip
|
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-win64-v2.3.1.zip
|
||||||
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v2.2/scrcpy-win32-v2.2.zip
|
[direct-win32]: https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-win32-v2.3.1.zip
|
||||||
|
|
||||||
and extract it.
|
and extract it.
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
BUILDDIR=build-auto
|
BUILDDIR=build-auto
|
||||||
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v2.2/scrcpy-server-v2.2
|
PREBUILT_SERVER_URL=https://github.com/Genymobile/scrcpy/releases/download/v2.3.1/scrcpy-server-v2.3.1
|
||||||
PREBUILT_SERVER_SHA256=c85c4aa84305efb69115cd497a120ebdd10258993b4cf123a8245b3d99d49874
|
PREBUILT_SERVER_SHA256=f6814822fc308a7a532f253485c9038183c6296a6c5df470a9e383b4f8e7605b
|
||||||
|
|
||||||
echo "[scrcpy] Downloading prebuilt server..."
|
echo "[scrcpy] Downloading prebuilt server..."
|
||||||
wget "$PREBUILT_SERVER_URL" -O scrcpy-server
|
wget "$PREBUILT_SERVER_URL" -O scrcpy-server
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
project('scrcpy', 'c',
|
project('scrcpy', 'c',
|
||||||
version: 'v2.2',
|
version: '2.3.1',
|
||||||
meson_version: '>= 0.48',
|
meson_version: '>= 0.48',
|
||||||
default_options: [
|
default_options: [
|
||||||
'c_std=c11',
|
'c_std=c11',
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ android {
|
|||||||
applicationId "com.genymobile.scrcpy"
|
applicationId "com.genymobile.scrcpy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 200
|
versionCode 20301
|
||||||
versionName "v2.2"
|
versionName "2.3.1"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
SCRCPY_DEBUG=false
|
SCRCPY_DEBUG=false
|
||||||
SCRCPY_VERSION_NAME=v2.2
|
SCRCPY_VERSION_NAME=2.3.1
|
||||||
|
|
||||||
PLATFORM=${ANDROID_PLATFORM:-34}
|
PLATFORM=${ANDROID_PLATFORM:-34}
|
||||||
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-34.0.0}
|
BUILD_TOOLS=${ANDROID_BUILD_TOOLS:-34.0.0}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public final class Workarounds {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void apply(boolean audio, boolean camera) {
|
public static void apply(boolean audio, boolean camera) {
|
||||||
|
boolean mustFillConfigurationController = false;
|
||||||
boolean mustFillAppInfo = false;
|
boolean mustFillAppInfo = false;
|
||||||
boolean mustFillAppContext = false;
|
boolean mustFillAppContext = false;
|
||||||
|
|
||||||
@@ -85,11 +86,23 @@ public final class Workarounds {
|
|||||||
mustFillAppContext = true;
|
mustFillAppContext = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
// On some Samsung devices, DisplayManagerGlobal.getDisplayInfoLocked() calls ActivityThread.currentActivityThread().getConfiguration(),
|
||||||
|
// which requires a non-null ConfigurationController.
|
||||||
|
// ConfigurationController was introduced in Android 12, so do not attempt to set it on lower versions.
|
||||||
|
// <https://github.com/Genymobile/scrcpy/issues/4467>
|
||||||
|
mustFillConfigurationController = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mustFillConfigurationController) {
|
||||||
|
// Must be call before fillAppContext() because it is necessary to get a valid system context
|
||||||
|
fillConfigurationController();
|
||||||
|
}
|
||||||
if (mustFillAppInfo) {
|
if (mustFillAppInfo) {
|
||||||
Workarounds.fillAppInfo();
|
fillAppInfo();
|
||||||
}
|
}
|
||||||
if (mustFillAppContext) {
|
if (mustFillAppContext) {
|
||||||
Workarounds.fillAppContext();
|
fillAppContext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +162,22 @@ public final class Workarounds {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void fillConfigurationController() {
|
||||||
|
try {
|
||||||
|
Class<?> configurationControllerClass = Class.forName("android.app.ConfigurationController");
|
||||||
|
Class<?> activityThreadInternalClass = Class.forName("android.app.ActivityThreadInternal");
|
||||||
|
Constructor<?> configurationControllerConstructor = configurationControllerClass.getDeclaredConstructor(activityThreadInternalClass);
|
||||||
|
configurationControllerConstructor.setAccessible(true);
|
||||||
|
Object configurationController = configurationControllerConstructor.newInstance(ACTIVITY_THREAD);
|
||||||
|
|
||||||
|
Field configurationControllerField = ACTIVITY_THREAD_CLASS.getDeclaredField("mConfigurationController");
|
||||||
|
configurationControllerField.setAccessible(true);
|
||||||
|
configurationControllerField.set(ACTIVITY_THREAD, configurationController);
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
Ln.d("Could not fill configuration: " + throwable.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Context getSystemContext() {
|
static Context getSystemContext() {
|
||||||
try {
|
try {
|
||||||
Method getSystemContextMethod = ACTIVITY_THREAD_CLASS.getDeclaredMethod("getSystemContext");
|
Method getSystemContextMethod = ACTIVITY_THREAD_CLASS.getDeclaredMethod("getSystemContext");
|
||||||
|
|||||||
Reference in New Issue
Block a user