Refactor the script

Add auto start adb (so you don't have to go developer settings anymore), Termux android notifications, and lastly you don't have to rerun script everytime you change IP anymore, the script will automatically reconnect for you.
This commit is contained in:
tretrauit 2022-02-04 22:34:21 +07:00
parent 22a8c52f48
commit 66d1e8f627
No known key found for this signature in database
GPG Key ID: 862760FF1903319E
2 changed files with 210 additions and 85 deletions

View File

@ -1,18 +1,31 @@
# ws-scrcpy scripts # ws-scrcpy scripts
## ws-scrcpy-launcher.py for Termux ## ws-scrcpy-launcher.py for Termux
### YOU NEED TO HAVE WS-SCRCPY INSTALLED, ALONG WITH ROOT ACCESS AND DEPENDENCIES
+ **YOU ALSO NEED TO OPEN ADB WIRELESS IN DEVELOPER SETTINGS FOR THIS TO WORK** ### Notes
+ root maybe not needed but **i haven't tested it yet** so do it with your own risk (the script won't fail even if it can't have root access btw)
+ dependencies: `root-repo` `tsu` `moreutils` `build-essential` `nodejs` `python3` `android-tools` `git` + **YOU NEED TO HAVE WS-SCRCPY INSTALLED, ALONG WITH ROOT ACCESS AND DEPENDENCIES**
+ you also need to downgrade npm to version 6 to fix npm on termux: `npm install -g npm@6` + ~~YOU ALSO NEED TO OPEN ADB WIRELESS IN DEVELOPER SETTINGS FOR THIS TO WORK~~ (The script can use `su` to start ADB wireless now)
> ignore the vulnerability please if you care about it please don't use this script + Rootless mode is available, although it **will not** work in most cases.
+ download ws-scrcpy-launcher.py: + Dependencies: `root-repo` `tsu` `moreutils` `build-essential` `nodejs` `python3` `android-tools` `git` `termux-api`
> Or execute `pkg install root-repo tsu moreutils build-essential nodejs python3 android-tools git termux-api`
+ You also need to downgrade npm to version 6 to fix Termux problem: `npm install -g npm@6`
> Please ignore the vulnerability message, if you care about it then please don't use this script.
+ Download ws-scrcpy-launcher.py:
```bash ```bash
curl -OL https://gitlab.com/tretrauit/scripts/-/raw/main/Apps/ws-scrcpy/ws-scrcpy-launcher.py curl -OL https://gitlab.com/tretrauit/scripts/-/raw/main/Apps/ws-scrcpy/ws-scrcpy-launcher.py
chmod +x ws-scrcpy-launcher.py chmod +x ws-scrcpy-launcher.py
``` ```
> after this use `./ws-scrcpy-launcher.py` to launch ws-scrcpy with scrcpy server for local device.
+ full script for lazy people (including install ws-scrcpy): > Execute `./ws-scrcpy-launcher.py` to launch ws-scrcpy with scrcpy server for local device.
+ Full script for lazy people (including install ws-scrcpy steps):
```bash ```bash
pkg update pkg update
pkg install root-repo moreutils build-essential nodejs python3 android-tools git pkg install root-repo moreutils build-essential nodejs python3 android-tools git
@ -25,5 +38,7 @@ npm install
curl -OL https://gitlab.com/tretrauit/scripts/-/raw/main/Apps/ws-scrcpy/ws-scrcpy-launcher.py curl -OL https://gitlab.com/tretrauit/scripts/-/raw/main/Apps/ws-scrcpy/ws-scrcpy-launcher.py
chmod +x ws-scrcpy-launcher.py chmod +x ws-scrcpy-launcher.py
``` ```
> after this you need to use `adb pair` to pair termux with your device adb server, then you can launch ws-scrcpy as explained above.
#### After this, the script will tell you to wait for ws-scrcpy to start, and when it starts it'll show the started message with the ip address and the port to access using browsers + The script will tell you to wait for ws-scrcpy to start, and when it starts it'll show the started message with the ip address and the port to access using browsers
> You need to use `adb pair` to pair termux with your device adb server, then you can launch ws-scrcpy as explained above.

View File

@ -1,106 +1,216 @@
#!/usr/bin/python3 #!/usr/bin/python3
# poorly written for quick and dirty use # Rewrite
import subprocess import subprocess
import os import os
import time import time
import threading import threading
import random
from pathlib import Path
from shutil import which
APP_UUID="a6db95c2-27db-4b88-a687-c8107d1bc9d6"
def Popen(args: list | str, root=False, shell=False, cwd=Path.cwd()):
if root:
if shell:
args = "sudo " + args
else:
args = ["sudo"] + args
result = subprocess.Popen(args, shell=shell, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return result
def run(args: list | str, root=False, shell=False, cwd=Path.cwd()):
if root:
if shell:
args = "sudo " + args
else:
args = ["sudo"] + args
result = subprocess.run(args, shell=shell, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result.check_returncode()
return result
def show_toast(message):
run(["termux-toast", f'{message}'])
def show_notification(title, message=None, vibration: list[int] | str=None, sound=False, ongoing=True):
if not which("termux-notification"):
raise FileNotFoundError("termux-notification not found, please install termux-api package and Termux:API app.")
args = ["termux-notification", "-i", APP_UUID, "--priority", "max", "-t", f'{title}']
if message:
args += ["-c", f'{message}']
if vibration:
args += ["--vibrate", ",".join(str(x) for x in vibration) if isinstance(vibration, list) else vibration]
if sound:
args += ["--sound"]
if ongoing:
args += ["--ongoing"]
run(args)
def get_device_private_ip():
return subprocess.check_output(['ifdata', '-pa', 'wlan0']).decode("utf-8").strip()
def get_port_from_process_name(name: str, state: str="LISTEN"):
lsof_output = subprocess.check_output(["sudo", "lsof", "-i", "-P", "-n"]).decode("utf-8")
for line in lsof_output.split("\n"):
if name in line and f"({state})" in line:
line = ' '.join(line.split())
return int(line.strip().split(" ")[8].split(":")[1])
return None
def get_pid_from_port(port: int, state: str="LISTEN"):
lsof_output = subprocess.check_output(["sudo", "lsof", "-i", "-P", "-n"]).decode("utf-8")
for line in lsof_output.split("\n"):
if str(port) in line and f"({state})" in line:
line = ' '.join(line.split())
return line.strip().split(" ")[1]
return None
def start_adbd():
free_port = random.randint(0, 65535)
while get_pid_from_port(free_port):
free_port = random.randint(0, 65535)
print("Starting adbd on port " + str(free_port))
show_notification("Starting adbd", "Starting adbd on port " + str(free_port))
try:
run(["setprop", "service.adb.tcp.port", str(free_port)], root=True)
except subprocess.CalledProcessError:
print("Failed to set adb port")
show_notification("Failed to set adb port to " + str(free_port), "You'll need to start adb manually through Developer Settings")
return
try:
run(["stop", "adbd"], root=True)
except subprocess.CalledProcessError:
print("Failed to stop adbd, maybe adbd was not running?")
try:
run(["start", "adbd"], root=True)
except subprocess.CalledProcessError:
print("Failed to start adbd")
show_notification("Failed to start adbd", "You'll need to start adb manually through Developer Settings")
return
return free_port
def connect_adb(ip, port):
run(["adb", "connect", f"{ip}:{port}"])
def main(): def main():
print("ws-scrcpy launcher for termux (YOU NEED TO HAVE WS-SCRCPY INSTALLED IN ~/ws-scrcpy)") print("ws-scrcpy launcher for Termux")
print("THIS SCRIPT REQUIRES ROOT AND TSU, THANK YOU :(") print("Checking for ws-scrcpy...")
print("checking for adb port...") if not Path("./ws-scrcpy").exists():
adb_lsof_output = subprocess.check_output(["sudo", "lsof", "-i", "-P", "-n"]).decode("utf-8") print("ws-scrcpy not found, please install ws-scrcpy.")
return
print("Checking for current adb port...")
show_notification("Checking for current adb port...")
adb_port = None adb_port = None
try: try:
for line in adb_lsof_output.split("\n"): adb_port = get_port_from_process_name("adbd")
if "adbd" in line and "(LISTEN)" in line:
line = ' '.join(line.split())
print(line.strip())
adb_port = line.strip().split(" ")[8].split(":")[1]
break
except: except:
print("error occured while getting adb port.")
pass pass
if adb_port == None: if adb_port is None:
adb_port = input("couldn't find adb port please type manually:") print("Failed to get adb port, starting new adbd...")
adb_port = start_adbd()
if adb_port is None:
print("Failed to start adbd...")
return
device_ip = subprocess.check_output(['ifdata', '-pa', 'wlan0']).decode("utf-8").strip() device_ip = get_device_private_ip()
print("adb port:", adb_port) print("Adb server port:", adb_port)
print("ip:", device_ip) print("Device IP:", device_ip)
print("connecting to device through adb...") print("Connecting to device through adb...")
connect_result = subprocess.call(["adb", "connect", f"{device_ip}:{adb_port}"]) show_notification("Connecting to device through adb...")
if connect_result != 0: try:
print("connection failed.") connect_adb(device_ip, adb_port)
exit() except subprocess.CalledProcessError:
print("changing directory to home") print("Failed to connect to device through adb")
os.chdir("/data/data/com.termux/files/home/") show_notification("Failed to connect to device through adb", "You'll need to connect manually in Termux.")
print("starting ws-scrcpy server...") return
ws_scrcpy = subprocess.Popen(["npm", "start"], cwd="./ws-scrcpy", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Starting ws-scrcpy server...")
show_notification("Starting ws-scrcpy server...", "You may need to wait for 5 minutes for ws-scrcpy to start.")
ws_scrcpy = Popen(["npm", "start"], cwd="./ws-scrcpy")
def print_ws_scrcpy(): def print_ws_scrcpy():
for line in ws_scrcpy.stdout: for line in ws_scrcpy.stdout:
if line.decode("utf-8").strip() is None: if line.decode("utf-8").strip() == None:
continue continue
if "Listening on:" in line.decode("utf-8").strip(): if "Listening on:" in line.decode("utf-8").strip():
device_ip = subprocess.check_output(['ifdata', '-pa', 'wlan0']).decode("utf-8").strip() device_ip = get_device_private_ip()
print("=========================================") print("=========================================")
print(f"ws-scrcpy STARTED ON {device_ip}:8000") print(f"ws-scrcpy started on {device_ip}:8000")
print("=========================================") print("=========================================")
show_toast(f"ws-scrcpy: {device_ip}:8000")
show_notification(f"ws-scrcpy: {device_ip}:8000", f"Access {device_ip}:8000 in browser to control the device.", [2000, 1000, 500], True)
print("[ws-scrcpy]:", line.decode("utf-8").strip()) print("[ws-scrcpy]:", line.decode("utf-8").strip())
ws_scrcpy_thread = threading.Thread(target=print_ws_scrcpy) ws_scrcpy_thread = threading.Thread(target=print_ws_scrcpy)
ws_scrcpy_thread.daemon = True ws_scrcpy_thread.daemon = True
ws_scrcpy_thread.start() ws_scrcpy_thread.start()
print("starting scrcpy server on local device...") # print("starting scrcpy server on local device...")
scrcpy = subprocess.Popen("adb shell su -c 'CLASSPATH=/data/data/com.termux/files/home/ws-scrcpy/vendor/Genymobile/scrcpy/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 1.19-ws2 web ERROR 8886'", # scrcpy = subprocess.Popen("adb shell su -c 'CLASSPATH=/data/data/com.termux/files/home/ws-scrcpy/vendor/Genymobile/scrcpy/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 1.19-ws2 web ERROR 8886'",
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def print_scrcpy(): # def print_scrcpy():
for line in scrcpy.stdout: # for line in scrcpy.stdout:
print("[scrcpy patch]:", line.decode("utf-8").strip()) # print("[scrcpy patch]:", line.decode("utf-8").strip())
scrcpy_thread = threading.Thread(target=print_scrcpy) # scrcpy_thread = threading.Thread(target=print_scrcpy)
scrcpy_thread.daemon = True # scrcpy_thread.daemon = True
scrcpy_thread.start() # scrcpy_thread.start()
print("PLEASE WAIT UNTIL WS-SCRCPY FULLY STARTS (ABOUT 5 MINS), IT TAKES A WHILE TO START THE SERVER.") print("PLEASE WAIT UNTIL WS-SCRCPY FULLY STARTS (ABOUT 5 MINS), IT TAKES A WHILE TO START THE SERVER.")
try: try:
while True: while True:
time.sleep(5) time.sleep(5)
curr_ip = subprocess.check_output(['ifdata', '-pa', 'wlan0']).decode("utf-8").strip() curr_ip = get_device_private_ip()
if curr_ip != device_ip: if curr_ip != device_ip:
print("!!!DEVICE IP ADDRESS CHANGED, PLEASE RESTART SERVER MANUALLY!!!") print("Device IP changed, reconnecting adb...")
print("!!!SCRCPY WILL NOT WORK UNTIL YOU RESTART THE SERVER!!!") show_notification("Reconnecting adb...", "This may take a while, take a cup of coffee.")
except: # lazy try:
if ws_scrcpy.poll() == None: connect_adb(curr_ip, adb_port)
print("stopping ws-scrcpy server...") except subprocess.CalledProcessError:
ws_scrcpy.terminate() print("Failed to connect to device through adb")
try: show_notification("Failed to connect to device through adb", "ws-scrcpy will be stopped.")
# if this returns, the process completed
ws_scrcpy.wait(timeout=15)
except subprocess.TimeoutExpired:
print("ws_scrcpy doesn't exit after 15 seconds, killing process...")
ws_scrcpy.kill()
print("stopping scrcpy server...")
if scrcpy.poll() == None:
scrcpy.terminate()
try:
# if this returns, the process completed
scrcpy.wait(timeout=15)
except subprocess.TimeoutExpired:
print("scrcpy doesn't exit after 15 seconds, killing process...")
scrcpy.kill()
# kill old scrcpy-server to ensure we can start a new one after this.
try:
lsof_output = subprocess.check_output(["sudo", "lsof", "-i", "-P", "-n"]).decode("utf-8")
for line in lsof_output.split("\n"):
if "8886" in line and "(LISTEN)" in line:
line = ' '.join(line.split())
print(line.strip())
pid = line.strip().split(" ")[1]
subprocess.call(["sudo", "kill", "-9", pid])
break break
except: device_ip = curr_ip
print("failed to stop scrcpy server") print("=========================================")
print("stopped.") print(f"ws-scrcpy started on {device_ip}:8000")
print("=========================================")
show_toast(f"ws-scrcpy: {device_ip}:8000")
show_notification(f"ws-scrcpy: {device_ip}:8000", f"Access {device_ip}:8000 in browser to control the device.", [2000, 1000, 500], True)
except:
pass
if ws_scrcpy.poll() == None:
print("Stopping ws-scrcpy server...")
show_notification("Stopping ws-scrcpy server...")
ws_scrcpy.terminate()
try:
# if this returns, the process completed
ws_scrcpy.wait(timeout=15)
except subprocess.TimeoutExpired:
print("ws_scrcpy doesn't exit after 15 seconds, killing process...")
ws_scrcpy.kill()
# print("stopping scrcpy server...")
# if scrcpy.poll() == None:
# scrcpy.terminate()
# try:
# # if this returns, the process completed
# scrcpy.wait(timeout=15)
# except subprocess.TimeoutExpired:
# print("scrcpy doesn't exit after 15 seconds, killing process...")
# scrcpy.kill()
# # kill old scrcpy-server to ensure we can start a new one after this.
# try:
# lsof_output = subprocess.check_output(["sudo", "lsof", "-i", "-P", "-n"]).decode("utf-8")
# for line in lsof_output.split("\n"):
# if "8886" in line and "(LISTEN)" in line:
# line = ' '.join(line.split())
# print(line.strip())
# pid = line.strip().split(" ")[1]
# subprocess.call(["sudo", "kill", "-9", pid])
# break
# except:
# print("failed to stop scrcpy server")
print("ws-scrcpy has been stopped.")
show_notification("ws-scrcpy has been stopped.", ongoing=False)
if __name__ == '__main__': if __name__ == '__main__':
main() main()