-
-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make scrcpy work with adb over tcpip #5
Comments
Yes, I planned to work on this. Here are the technical details: https://news.ycombinator.com/item?id=16546276
|
I just used it with adb connect. It worked fine. |
@Yeradon Hmm… It does not work for me:
|
I was using wireless hotspot from my phone to setup the network. Maybe that makes a difference? |
@Yeradon Created a hotspot with phone and connected computer to it. Then adb connected and run scrcpy, still same error as above. |
Oops, sorry, that bug languished partly because it was assigned to the wrong person. However, you might be able to sidestep that by communicating with your device-side process directly via stdin/stdout, instead of having it connect to a forwarded port. It should have identical throughput and start up faster, too. |
Thank you for your investigations ;-)
😞
In my first PoC, I used stdout to stream the video. However:
This is for the device-to-computer communication. But in both direction, how do you do that? |
Looks like it was added around Lollipop (API level 20), which is earlier than your minimum supporter version: https://android.googlesource.com/platform/system/core/+/lollipop-release/adb/services.c#426
Yeah, this is caused by the device-side adb daemon allocating a TTY instead of a pipe for stdout. exec-in/exec-out solve that by creating a pipe, but they're unidirectional [1] because the adb protocol didn't specify a way to half close a socket, so you'd end up hanging forever. There's a new shell protocol that was added in N that fixes that by adding another protocol on top that allows each side to tell the other that their stdin is closed. If you're willing to limit yourself to N+, (Or if you're willing to do dirty hacks, you could do something terrible like base64 encoding your output)
A sufficiently new version of the adb client shouldn't be subject to this (patch that fixed this is https://android.googlesource.com/platform/system/core/+/1fc8f6e0cfdfd5c9dbbd82116fba2ebec82b4659)
Isn't it? There's problems with detecting when your local stdin closes, but AFAIK, this should work even on ancient devices. I dug up the oldest device I could find roughly available, and it seems to be working as expected (i.e. broken, because the terminal isn't raw mode, so it's mirroring the input and then repeating it via cat). [1] There's no inherent limitation to keep you from using exec bidirectionally, the command line client just does it to keep people from doing things that will just hang. I'm not suggesting that you do it, but you could connect to the adb server yourself and |
Wow, thank you for all this relevant information 👍
IIUC, in that case, if the device is unplugged while running, the server keeps running? |
"adb reverse" currently does not work over tcpip (i.e. on a device connected by "adb connect"): <https://issuetracker.google.com/issues/37066218> To work around the problem, if the call to "adb reverse" fails, then fallback to "adb forward", and reverse the client/server roles. Keep the "adb reverse" mode as the default because it does not involve connection retries: when using "adb forward", the client must try to connect successively until the server listens. Due to the tunnel, every connect() will succeed, so the client must attempt to read() to detect a connection failure. For this purpose, when using the "adb forward" mode, the server initially writes a dummy byte, read by the client. Fixes <#5>.
I implemented what I explained in my comment, please checkout the
To switch back your device to USB mode: Note that while it now works over tcpip, this is not an optimal solution for streaming a video wirelessly, since the raw stream is still sent over TCP, where a packet loss is very bad for latency, due to head-of-line blocking. As expected, it is better when the device is plugged. 🙂 If everything is ok, I'll probably publish a new release soon 😉 |
"adb reverse" currently does not work over tcpip (i.e. on a device connected by "adb connect"): <https://issuetracker.google.com/issues/37066218> To work around the problem, if the call to "adb reverse" fails, then fallback to "adb forward", and reverse the client/server roles. Keep the "adb reverse" mode as the default because it does not involve connection retries: when using "adb forward", the client must try to connect successively until the server listens. Due to the tunnel, every connect() will succeed, so the client must attempt to read() to detect a connection failure. For this purpose, when using the "adb forward" mode, the server initially writes a dummy byte, read by the client. Fixes <#5>.
@rom1v awesome! it works for me. It's quite laggy but I guess that was expected. |
Depending on the use case, I think that reducing the bitrate and resolution may be a good compromise:
|
I believe this should work (but haven't verified it on an old device). Unplugging the device/ctrl-c should close everything; the problem stems from not being able to report EOF of your write end, and continue waiting for output from the other side. (e.g. the exec moral equivalent of |
|
@rom1v I get the same error as you:
I don't know what's causing this issue because I followed your instructions: #5 (comment) |
@unixfox, Did you compile the |
@rom1v Yes I did. |
That's the problem: you need the changes for the server too.
No, it seems that's in their own app. |
We just released v1.1 including this fix: Scrcpy now works wirelessly. |
Will the issue be fixes in the near future?
|
this will allow scrcpy to work wirelessly |
Question: Do we have to every time first connect via usb and then switch wireless or its just first time? |
On Linux, socket functions are unblocked by shutdown(), but on Windows they are unblocked by closesocket(). Expose net_interrupt() and net_close() to abstract these differences: - net_interrupt() calls shutdown() on Linux and closesocket() on Windows (if not already called); - net_close() calls close() on Linux and closesocket() on Windows (if not already called). This simplifies the server code, and prevents a data race on close (reported by TSAN) on Linux (but does not fix it on Windows): WARNING: ThreadSanitizer: data race (pid=836124) Write of size 8 at 0x7ba0000000d0 by main thread: #0 close ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1690 (libtsan.so.0+0x359d8) #1 net_close ../app/src/util/net.c:211 (scrcpy+0x1c76b) #2 close_socket ../app/src/server.c:330 (scrcpy+0x19442) #3 server_stop ../app/src/server.c:522 (scrcpy+0x19e33) #4 scrcpy ../app/src/scrcpy.c:532 (scrcpy+0x156fc) #5 main ../app/src/main.c:92 (scrcpy+0x622a) Previous read of size 8 at 0x7ba0000000d0 by thread T6: #0 recv ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:6603 (libtsan.so.0+0x4f4a6) #1 net_recv ../app/src/util/net.c:167 (scrcpy+0x1c5a7) #2 run_receiver ../app/src/receiver.c:76 (scrcpy+0x12819) #3 <null> <null> (libSDL2-2.0.so.0+0x84f40)
On Linux, socket functions are unblocked by shutdown(), but on Windows they are unblocked by closesocket(). Expose net_interrupt() and net_close() to abstract these differences: - net_interrupt() calls shutdown() on Linux and closesocket() on Windows (if not already called); - net_close() calls close() on Linux and closesocket() on Windows (if not already called). This simplifies the server code, and prevents a data race on close (reported by TSAN) on Linux (but does not fix it on Windows): WARNING: ThreadSanitizer: data race (pid=836124) Write of size 8 at 0x7ba0000000d0 by main thread: #0 close ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1690 (libtsan.so.0+0x359d8) #1 net_close ../app/src/util/net.c:211 (scrcpy+0x1c76b) #2 close_socket ../app/src/server.c:330 (scrcpy+0x19442) #3 server_stop ../app/src/server.c:522 (scrcpy+0x19e33) #4 scrcpy ../app/src/scrcpy.c:532 (scrcpy+0x156fc) #5 main ../app/src/main.c:92 (scrcpy+0x622a) Previous read of size 8 at 0x7ba0000000d0 by thread T6: #0 recv ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:6603 (libtsan.so.0+0x4f4a6) #1 net_recv ../app/src/util/net.c:167 (scrcpy+0x1c5a7) #2 run_receiver ../app/src/receiver.c:76 (scrcpy+0x12819) #3 <null> <null> (libSDL2-2.0.so.0+0x84f40)
Help me... i have error: [server] ERROR: Could not invoke method |
@AdmoMontes https://github.com/Genymobile/scrcpy/blob/master/FAQ.md#mouse-and-keyboard-do-not-work (but this is not the right place to ask, this issue is about adb over tcpip) |
Great useful tool. Thank you.
It would be really cool if the device did not have to be connected via usb.
The text was updated successfully, but these errors were encountered: