Незаметный цифровой помощник
Сначала я, конечно, попробовал найти готовое решение. Приложения из Google Play типа Volume Limiter или Volume Control разочаровали: они часто вылетали, иногда по непонятным причинам переставали ограничивать громкость и, вообще, были неудобными. Возможно, платные приложения работают лучше, но зачем платить, если можно решить проблему самому?
Я создал скрипт, который подключается к Android-устройству по Wi-Fi и следит за громкостью. Если звук становится слишком громким — он плавно убавляет его. Никаких остановок видео, никакого видимого уменьшения громкости на экране, никакого взаимодействия с пользователем. Просто магия.
Технически я использовал ADB (Android Debug Bridge) по Wi-Fi — инструмент разработчика, который не предназначен для обычного пользователя. Именно поэтому он скрыт, и его надо сначала активировать. Но в этом и есть простота и элегантность решения.
Принцип работы
Ваш компьютер подключается к Android-устройству через ADB по Wi-Fi, периодически проверяет громкость и при необходимости снижает ее.

Каждые 30 секунд скрипт проверяет текущую громкость звука (Android обычно использует 15-балльную шкалу). Если значение выше 5, скрипт снижает его по единице за раз, с короткими паузами. Звук стихает очень плавно и мягко, чтобы не нарушать процесс засыпания.
Если громкость уже на уровне 5 или ниже, скрипт ничего не делает и просто ждет, вдруг громкость снова повысят. А когда пользователь сам убавляет звук, то скрипт это тоже замечает и не вмешивается.
Эволюция скрипта
Когда я впервые написал этот скрипт, он был длиной всего в несколько строк. Но быстро стало понятно: а что, если устройство отключится посреди ночи? Что, если ADB выдаст таймаут? Что, если скрипт упадет, пока все спят?
Именно поэтому я дорабатывал скрипт по результатам тестирования и постепенно добавил:
- автоматическое переподключение, если устройство отключилось;
- обработку исключений и повторные попытки;
- логирование в файл и консоль, чтобы утром можно было проанализировать сон человека;
- отслеживание громкости во время сна, чтобы скрипт вмешивался только при необходимости;
- разные интервалы мониторинга для высокого и низкого уровня громкости;
- корректное завершение работы по Ctrl + C.
То, что начиналось как несколько строк кода, превратилось в маленькое приложение, которое присматривает за вашим телефоном, чтобы вам не пришлось это делать самому.
Финальная версия скрипта
Ниже полный код скрипта, в том виде, в каком я сейчас его использую.
#!/usr/bin/env python3
import subprocess
import time
import re
import logging
from datetime import datetime
logging.basicConfig(
filename=f'{datetime.now().strftime("%Y%m%d")}-volume_control.log',
level=logging.INFO,
format='[%(asctime)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
ADB_DEVICE = "10.0.0.59:5555" # Замените на IP-адрес вашего устройства
ADB = '/usr/local/bin/adb'
def log(message):
timestamp = get_timestamp()
print(f'[{timestamp}] {message}')
logging.info(message)
def get_timestamp():
return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
def connect_adb():
subprocess.run(f"{ADB} connect {ADB_DEVICE}", shell=True)
log(f" Переподключение к {ADB} по адресу {ADB_DEVICE}")
def get_stream_volume():
"""Возвращает значение streamVolume, если найдено, иначе None."""
cmd = f"{ADB} shell dumpsys audio | awk '/- STREAM_MUSIC:/{{flag=1; count=0}} flag && count<=5
{{print; count++}} /^$/{{flag=0}}'"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
match = re.search(r'streamVolume:(d+)', result.stdout)
return int(match.group(1)) if match else None
def safe_get_stream_volume(retries=3, delay=5):
"""Безопасное получение громкости, с попытками переподключения."""
for attempt in range(retries):
volume = get_stream_volume()
if volume is not None:
return volume
log(f"Попытка {attempt + 1}: Не удалось получить громкость. Повтор после переподключения...")
connect_adb()
time.sleep(delay)
log("Все попытки неудачны. Временная остановка попыток.")
return None
def set_volume(level):
cmd = f"{ADB} shell cmd media_session volume --stream 3 --set {level} > /dev/null 2>&1"
subprocess.run(cmd, shell=True)
log(f"Громкость установлена на {level}, ожидание 30 секунд...")
def monitor_volume():
"""Основной цикл мониторинга и регулировки громкости."""
while True:
volume = safe_get_stream_volume()
if volume is None:
log("Не удалось прочитать начальную громкость. Повтор через 30 секунд...")
time.sleep(30)
continue
log(f"Текущий уровень громкости: {volume}")
while volume > 5:
set_volume(volume - 1)
time.sleep(10)
volume = safe_get_stream_volume()
if volume is None:
log("Не удалось прочитать громкость во время снижения")
break
while True:
volume = safe_get_stream_volume()
if volume is None:
log("Не удалось прочитать громкость во время мониторинга.")
time.sleep(30)
break
if volume > 5:
log(f"Громкость увеличена до {volume}, перезапуск снижения.")
break
log(f"Громкость установлена на {volume}, мониторинг каждые 60 секунд...")
time.sleep(60)
if __name__ == "__main__":
try:
monitor_volume()
except KeyboardInterrupt:
log("Скрипт остановлен пользователем (Ctrl+C)")
except Exception as e:
log(f"Неожиданная ошибка: {e}")
finally:
log("Скрипт завершен.")
Как запускать скрипт
Для запуска скрипта есть несколько вариантов:
- Напрямую через Python. Если у вас установлен Python 3, просто запустите:
python3 volume_control.py
Как автономное приложение. Хотите поделиться с кем-то, у кого нет Python? Можете преобразовать скрипт в автономное приложение с помощью PyInstaller:
pyinstaller --onefile volume_control.py
По расписанию. Можете даже настроить автоматический запуск через cron (Linux/macOS) или планировщик задач (Windows).
Ограничения ADB по Wi-Fi
ADB по Wi-Fi может перестать работать по нескольким причинам:
- Телефон перезагрузится.
- Изменится Wi-Fi-сеть.
- Отключится режим разработчика или USB-отладка.
- Устройство слишком долго не будет иметь ADB-активности.
- Возможно, есть что-то еще, но я пока это не выявил.
Но это не страшно, так как всё можно быстро и легко исправить. Если скрипт перестал работать, просто повторите шаги подключения:
- Подключите устройство по USB-кабелю к компьютеру.
- Выполните
adb tcpip 5555
. Выполните adb connect <IP_УСТРОЙСТВА>:5555
.
И скрипт снова будет выполнять свою функцию — мягко и ненавязчиво корректировать звук.
Заключение
Этот лайфхак создан не для того, чтобы ограничить чьи-то привычки засыпать под видео. Наоборот, он помогает защитить сон от неожиданной рекламы или слишком громкого звука при автовоспроизведении следующего видео.
Возможно, это всего-навсего маленький скрипт, но для моей семьи и меня он стал настоящим помощником. Больше нет пробуждений от YouTube в два ночи и капризов у ребенка из-за того, что он долго засыпал. Просто спокойные ночи и немного автоматизации.
А вообще, этот скрипт работает не только для детей. Он поможет и взрослым, которых бесит внезапное увеличение громкости в видео, когда уже почти заснул (или давно видишь сон). Он простой, незаметный и ненавязчивый. И он работает.
Спокойных вам ночей. Вы их заслужили.
P. S. Это решение можно улучшить и расширить: например, настроить расписание, адаптировать под разные профили, отслеживать активность устройства и т. д. Но даже в базовой форме оно уже решает главную проблему — помогает заснуть и спать спокойно.