Files
phonestream/phonestream-tray.py

133 lines
3.9 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
PhoneStream Tray — иконка в системном трее.
Запуск: python3 phonestream-tray.py
Зависимости: gir1.2-appindicator3-0.1 (sudo apt install gir1.2-appindicator3-0.1)
"""
import subprocess
import threading
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, GLib
from gi.repository import AppIndicator3 as AppIndicator
SCRIPT = "/home/nikolas/bin/phonestream/phonestream.sh"
PHONE_ID = "c3c2c293"
PROFILES = [
(0, "▶ Максимум (5MP 4:3)", "start", "0"),
(1, "▶ Широкий (4MP 16:9)", "start", "1"),
(2, "▶ 2.5K (5MP 4:3)", "start", "2"),
(3, "▶ Full HD", "start", "3"),
(4, "▶ Full HD 60fps", "start", "4"),
(5, "▶ HD 120fps (slow-mo)", "start", "5"),
(6, "▶ HD 240fps (slow-mo)", "start", "6"),
]
def is_stream_active():
try:
r = subprocess.run(["pgrep", "-f", "scrcpy.*v4l2-sink"],
capture_output=True, text=True, timeout=2)
return r.returncode == 0
except Exception:
return False
def is_phone_connected():
try:
r = subprocess.run(["adb", "devices"],
capture_output=True, text=True, timeout=3)
return PHONE_ID in r.stdout
except Exception:
return False
def run_script(args):
def _run():
try:
subprocess.run([SCRIPT] + args, capture_output=True, text=True, timeout=15)
except Exception:
pass
threading.Thread(target=_run, daemon=True).start()
def make_menu():
phone_ok = is_phone_connected()
stream_active = is_stream_active()
menu = Gtk.Menu()
# Статус
phone_item = Gtk.MenuItem(label=f"📱 Телефон: {'Подключён' if phone_ok else 'Нет'}")
phone_item.set_sensitive(False)
menu.append(phone_item)
stream_item = Gtk.MenuItem(label=f"📷 Стрим: {'Активен ●' if stream_active else 'Стоп ○'}")
stream_item.set_sensitive(False)
menu.append(stream_item)
menu.append(Gtk.SeparatorMenuItem())
if not stream_active:
# Запуск с профилем
for idx, label, action, profile_idx in PROFILES:
item = Gtk.MenuItem(label=label)
item.connect("activate", lambda i, p=profile_idx: run_script(["start", p]))
menu.append(item)
else:
# Остановка
stop_item = Gtk.MenuItem(label="⏹ Остановить")
stop_item.connect("activate", lambda i: run_script(["stop"]))
menu.append(stop_item)
# Перезапуск
menu.append(Gtk.SeparatorMenuItem())
for idx, label, action, profile_idx in PROFILES:
restart_label = label.replace("▶", "🔄")
item = Gtk.MenuItem(label=restart_label)
item.connect("activate", lambda i, p=profile_idx: run_script(["restart", p]))
menu.append(item)
menu.append(Gtk.SeparatorMenuItem())
status_item = Gtk.MenuItem(label="📊 Статус")
status_item.connect("activate", lambda i: run_script(["status"]))
menu.append(status_item)
quit_item = Gtk.MenuItem(label="✕ Выход из трея")
quit_item.connect("activate", lambda i: Gtk.main_quit())
menu.append(quit_item)
menu.show_all()
return menu
def main():
indicator = AppIndicator.Indicator.new(
"phonestream",
"camera-web",
AppIndicator.IndicatorCategory.HARDWARE
)
indicator.set_status(AppIndicator.IndicatorStatus.ACTIVE)
indicator.set_title("PhoneStream")
indicator.set_menu(make_menu())
# Обновление меню каждые 3 сек
def refresh(ind):
ind.set_menu(make_menu())
return True
GLib.timeout_add_seconds(3, refresh, indicator)
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
if __name__ == "__main__":
main()