Merge branch 'master' into dev
This commit is contained in:
commit
ca970e8aa6
8 changed files with 77 additions and 39 deletions
1
LICENSE
1
LICENSE
|
@ -188,6 +188,7 @@
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright (C) 2018 Genymobile
|
Copyright (C) 2018 Genymobile
|
||||||
|
Copyright (C) 2018-2019 Romain Vimont
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -44,7 +44,7 @@ clean:
|
||||||
build-server:
|
build-server:
|
||||||
[ -d "$(SERVER_BUILD_DIR)" ] || ( mkdir "$(SERVER_BUILD_DIR)" && \
|
[ -d "$(SERVER_BUILD_DIR)" ] || ( mkdir "$(SERVER_BUILD_DIR)" && \
|
||||||
meson "$(SERVER_BUILD_DIR)" \
|
meson "$(SERVER_BUILD_DIR)" \
|
||||||
--buildtype release -Dbuild_app=false )
|
--buildtype release -Dcompile_app=false )
|
||||||
ninja -C "$(SERVER_BUILD_DIR)"
|
ninja -C "$(SERVER_BUILD_DIR)"
|
||||||
|
|
||||||
prepare-deps-win32:
|
prepare-deps-win32:
|
||||||
|
@ -56,7 +56,7 @@ build-win32: prepare-deps-win32
|
||||||
--cross-file cross_win32.txt \
|
--cross-file cross_win32.txt \
|
||||||
--buildtype release --strip -Db_lto=true \
|
--buildtype release --strip -Db_lto=true \
|
||||||
-Dcrossbuild_windows=true \
|
-Dcrossbuild_windows=true \
|
||||||
-Dbuild_server=false \
|
-Dcompile_server=false \
|
||||||
-Dportable=true )
|
-Dportable=true )
|
||||||
ninja -C "$(WIN32_BUILD_DIR)"
|
ninja -C "$(WIN32_BUILD_DIR)"
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ build-win32-noconsole: prepare-deps-win32
|
||||||
--cross-file cross_win32.txt \
|
--cross-file cross_win32.txt \
|
||||||
--buildtype release --strip -Db_lto=true \
|
--buildtype release --strip -Db_lto=true \
|
||||||
-Dcrossbuild_windows=true \
|
-Dcrossbuild_windows=true \
|
||||||
-Dbuild_server=false \
|
-Dcompile_server=false \
|
||||||
-Dwindows_noconsole=true \
|
-Dwindows_noconsole=true \
|
||||||
-Dportable=true )
|
-Dportable=true )
|
||||||
ninja -C "$(WIN32_NOCONSOLE_BUILD_DIR)"
|
ninja -C "$(WIN32_NOCONSOLE_BUILD_DIR)"
|
||||||
|
@ -80,7 +80,7 @@ build-win64: prepare-deps-win64
|
||||||
--cross-file cross_win64.txt \
|
--cross-file cross_win64.txt \
|
||||||
--buildtype release --strip -Db_lto=true \
|
--buildtype release --strip -Db_lto=true \
|
||||||
-Dcrossbuild_windows=true \
|
-Dcrossbuild_windows=true \
|
||||||
-Dbuild_server=false \
|
-Dcompile_server=false \
|
||||||
-Dportable=true )
|
-Dportable=true )
|
||||||
ninja -C "$(WIN64_BUILD_DIR)"
|
ninja -C "$(WIN64_BUILD_DIR)"
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ build-win64-noconsole: prepare-deps-win64
|
||||||
--cross-file cross_win64.txt \
|
--cross-file cross_win64.txt \
|
||||||
--buildtype release --strip -Db_lto=true \
|
--buildtype release --strip -Db_lto=true \
|
||||||
-Dcrossbuild_windows=true \
|
-Dcrossbuild_windows=true \
|
||||||
-Dbuild_server=false \
|
-Dcompile_server=false \
|
||||||
-Dwindows_noconsole=true \
|
-Dwindows_noconsole=true \
|
||||||
-Dportable=true )
|
-Dportable=true )
|
||||||
ninja -C "$(WIN64_NOCONSOLE_BUILD_DIR)"
|
ninja -C "$(WIN64_NOCONSOLE_BUILD_DIR)"
|
||||||
|
|
51
README.md
51
README.md
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
This application provides display and control of Android devices connected on
|
This application provides display and control of Android devices connected on
|
||||||
USB (or [over TCP/IP][article-tcpip]). It does not require any _root_ access.
|
USB (or [over TCP/IP][article-tcpip]). It does not require any _root_ access.
|
||||||
It works on _GNU/Linux_, _Windows_ and _MacOS_.
|
It works on _GNU/Linux_, _Windows_ and _macOS_.
|
||||||
|
|
||||||
![screenshot](assets/screenshot-debian-600.jpg)
|
![screenshot](assets/screenshot-debian-600.jpg)
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
The Android part requires at least API 21 (Android 5.0).
|
The Android device requires at least API 21 (Android 5.0).
|
||||||
|
|
||||||
Make sure you [enabled adb debugging][enable-adb] on your device(s).
|
Make sure you [enabled adb debugging][enable-adb] on your device(s).
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ For Windows, for simplicity, prebuilt archives with all the dependencies
|
||||||
You can also [build the app manually][BUILD].
|
You can also [build the app manually][BUILD].
|
||||||
|
|
||||||
|
|
||||||
### Mac OS
|
### macOS
|
||||||
|
|
||||||
The application is available in [Homebrew]. Just install it:
|
The application is available in [Homebrew]. Just install it:
|
||||||
|
|
||||||
|
@ -101,16 +101,16 @@ scrcpy --help
|
||||||
### Reduce size
|
### Reduce size
|
||||||
|
|
||||||
Sometimes, it is useful to mirror an Android device at a lower definition to
|
Sometimes, it is useful to mirror an Android device at a lower definition to
|
||||||
increase performances.
|
increase performance.
|
||||||
|
|
||||||
To limit both width and height to some value (e.g. 1024):
|
To limit both the width and height to some value (e.g. 1024):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scrcpy --max-size 1024
|
scrcpy --max-size 1024
|
||||||
scrcpy -m 1024 # short version
|
scrcpy -m 1024 # short version
|
||||||
```
|
```
|
||||||
|
|
||||||
The other dimension is computed to that the device aspect-ratio is preserved.
|
The other dimension is computed to that the device aspect ratio is preserved.
|
||||||
That way, a device in 1920×1080 will be mirrored at 1024×576.
|
That way, a device in 1920×1080 will be mirrored at 1024×576.
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ scrcpy -b 2M # short version
|
||||||
|
|
||||||
The device screen may be cropped to mirror only part of the screen.
|
The device screen may be cropped to mirror only part of the screen.
|
||||||
|
|
||||||
This is useful for example to mirror only 1 eye of the Oculus Go:
|
This is useful for example to mirror only one eye of the Oculus Go:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
scrcpy --crop 1224:1440:0:0 # 1224x1440 at offset (0,0)
|
scrcpy --crop 1224:1440:0:0 # 1224x1440 at offset (0,0)
|
||||||
|
@ -312,24 +312,24 @@ Also see [issue #14].
|
||||||
|
|
||||||
| Action | Shortcut |
|
| Action | Shortcut |
|
||||||
| -------------------------------------- |:---------------------------- |
|
| -------------------------------------- |:---------------------------- |
|
||||||
| switch fullscreen mode | `Ctrl`+`f` |
|
| Switch fullscreen mode | `Ctrl`+`f` |
|
||||||
| resize window to 1:1 (pixel-perfect) | `Ctrl`+`g` |
|
| Resize window to 1:1 (pixel-perfect) | `Ctrl`+`g` |
|
||||||
| resize window to remove black borders | `Ctrl`+`x` \| _Double-click¹_ |
|
| Resize window to remove black borders | `Ctrl`+`x` \| _Double-click¹_ |
|
||||||
| click on `HOME` | `Ctrl`+`h` \| _Middle-click_ |
|
| Click on `HOME` | `Ctrl`+`h` \| _Middle-click_ |
|
||||||
| click on `BACK` | `Ctrl`+`b` \| _Right-click²_ |
|
| Click on `BACK` | `Ctrl`+`b` \| _Right-click²_ |
|
||||||
| click on `APP_SWITCH` | `Ctrl`+`s` |
|
| Click on `APP_SWITCH` | `Ctrl`+`s` |
|
||||||
| click on `MENU` | `Ctrl`+`m` |
|
| Click on `MENU` | `Ctrl`+`m` |
|
||||||
| click on `VOLUME_UP` | `Ctrl`+`↑` _(up)_ (`Cmd`+`↑` on MacOS) |
|
| Click on `VOLUME_UP` | `Ctrl`+`↑` _(up)_ (`Cmd`+`↑` on macOS) |
|
||||||
| click on `VOLUME_DOWN` | `Ctrl`+`↓` _(down)_ (`Cmd`+`↓` on MacOS) |
|
| Click on `VOLUME_DOWN` | `Ctrl`+`↓` _(down)_ (`Cmd`+`↓` on macOS) |
|
||||||
| click on `POWER` | `Ctrl`+`p` |
|
| Click on `POWER` | `Ctrl`+`p` |
|
||||||
| power on | _Right-click²_ |
|
| Power on | _Right-click²_ |
|
||||||
| turn device screen off (keep mirroring)| `Ctrl`+`o` |
|
| Turn device screen off (keep mirroring)| `Ctrl`+`o` |
|
||||||
| expand notification panel | `Ctrl`+`n` |
|
| Expand notification panel | `Ctrl`+`n` |
|
||||||
| collapse notification panel | `Ctrl`+`Shift`+`n` |
|
| Collapse notification panel | `Ctrl`+`Shift`+`n` |
|
||||||
| copy device clipboard to computer | `Ctrl`+`c` |
|
| Copy device clipboard to computer | `Ctrl`+`c` |
|
||||||
| paste computer clipboard to device | `Ctrl`+`v` |
|
| Paste computer clipboard to device | `Ctrl`+`v` |
|
||||||
| copy computer clipboard to device | `Ctrl`+`Shift`+`v` |
|
| Copy computer clipboard to device | `Ctrl`+`Shift`+`v` |
|
||||||
| enable/disable FPS counter (on stdout) | `Ctrl`+`i` |
|
| Enable/disable FPS counter (on stdout) | `Ctrl`+`i` |
|
||||||
|
|
||||||
_¹Double-click on black borders to remove them._
|
_¹Double-click on black borders to remove them._
|
||||||
_²Right-click turns the screen on if it was off, presses BACK otherwise._
|
_²Right-click turns the screen on if it was off, presses BACK otherwise._
|
||||||
|
@ -380,6 +380,7 @@ Read the [developers page].
|
||||||
## Licence
|
## Licence
|
||||||
|
|
||||||
Copyright (C) 2018 Genymobile
|
Copyright (C) 2018 Genymobile
|
||||||
|
Copyright (C) 2018-2019 Romain Vimont
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -151,9 +151,6 @@ recorder_write_header(struct recorder *recorder, const AVPacket *packet) {
|
||||||
int ret = avformat_write_header(recorder->ctx, NULL);
|
int ret = avformat_write_header(recorder->ctx, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOGE("Failed to write header to %s", recorder->filename);
|
LOGE("Failed to write header to %s", recorder->filename);
|
||||||
SDL_free(extradata);
|
|
||||||
avio_closep(&recorder->ctx->pb);
|
|
||||||
avformat_free_context(recorder->ctx);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ run_stream(void *data) {
|
||||||
|
|
||||||
if (stream->recorder && !recorder_open(stream->recorder, codec)) {
|
if (stream->recorder && !recorder_open(stream->recorder, codec)) {
|
||||||
LOGE("Could not open recorder");
|
LOGE("Could not open recorder");
|
||||||
goto finally_close_input;
|
goto finally_close_decoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVPacket packet;
|
AVPacket packet;
|
||||||
|
@ -248,6 +248,10 @@ quit:
|
||||||
if (stream->recorder) {
|
if (stream->recorder) {
|
||||||
recorder_close(stream->recorder);
|
recorder_close(stream->recorder);
|
||||||
}
|
}
|
||||||
|
finally_close_decoder:
|
||||||
|
if (stream->decoder) {
|
||||||
|
decoder_close(stream->decoder);
|
||||||
|
}
|
||||||
finally_close_input:
|
finally_close_input:
|
||||||
avformat_close_input(&format_ctx);
|
avformat_close_input(&format_ctx);
|
||||||
finally_free_avio_ctx:
|
finally_free_avio_ctx:
|
||||||
|
|
|
@ -3,11 +3,11 @@ project('scrcpy', 'c',
|
||||||
meson_version: '>= 0.37',
|
meson_version: '>= 0.37',
|
||||||
default_options: 'c_std=c11')
|
default_options: 'c_std=c11')
|
||||||
|
|
||||||
if get_option('build_app')
|
if get_option('compile_app')
|
||||||
subdir('app')
|
subdir('app')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('build_server')
|
if get_option('compile_server')
|
||||||
subdir('server')
|
subdir('server')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
option('build_app', type: 'boolean', value: true, description: 'Build the client')
|
option('compile_app', type: 'boolean', value: true, description: 'Build the client')
|
||||||
option('build_server', type: 'boolean', value: true, description: 'Build the server')
|
option('compile_server', type: 'boolean', value: true, description: 'Build the server')
|
||||||
option('crossbuild_windows', type: 'boolean', value: false, description: 'Build for Windows from Linux')
|
option('crossbuild_windows', type: 'boolean', value: false, description: 'Build for Windows from Linux')
|
||||||
option('windows_noconsole', type: 'boolean', value: false, description: 'Disable console on Windows (pass -mwindows flag)')
|
option('windows_noconsole', type: 'boolean', value: false, description: 'Disable console on Windows (pass -mwindows flag)')
|
||||||
option('prebuilt_server', type: 'string', description: 'Path of the prebuilt server')
|
option('prebuilt_server', type: 'string', description: 'Path of the prebuilt server')
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.genymobile.scrcpy;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class DeviceMessageWriterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSerializeClipboard() throws IOException {
|
||||||
|
DeviceMessageWriter writer = new DeviceMessageWriter();
|
||||||
|
|
||||||
|
String text = "aéûoç";
|
||||||
|
byte[] data = text.getBytes(StandardCharsets.UTF_8);
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(bos);
|
||||||
|
dos.writeByte(DeviceMessage.TYPE_CLIPBOARD);
|
||||||
|
dos.writeShort(data.length);
|
||||||
|
dos.write(data);
|
||||||
|
|
||||||
|
byte[] expected = bos.toByteArray();
|
||||||
|
|
||||||
|
DeviceMessage msg = DeviceMessage.createClipboard(text);
|
||||||
|
bos = new ByteArrayOutputStream();
|
||||||
|
writer.writeTo(msg, bos);
|
||||||
|
|
||||||
|
byte[] actual = bos.toByteArray();
|
||||||
|
|
||||||
|
Assert.assertArrayEquals(expected, actual);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue