Disclaimer: This article is for educational purposes only. Don't break the law, be nice to your kids, and don't forget that you're responsible for what you do with your own devices.
The Problem No One Talks About
The Digital Sleep Paradox In an era where screens dominate bedtime routines, millions now fall asleep to YouTube videos, podcasts, or streaming apps.
However, this habit has a hidden cost: uncontrolled volume exposure, especially for children. As a parent and developer, I faced this problem firsthand—my child’s late-night YouTube binges led to restless sleep and morning irritability.
Free apps in the Google Play Store, like Volume Limiter, Volume Control were a failure: they crashed, had no settings, or were too intrusive. Perhaps commercial apps would be better, but I haven't tested this since they cost money, often quite a bit.
The Hack (Totally Illegal…ish)
I built a script that connects to your Android device wirelessly and keeps an eye on its volume. If it gets too loud — it gently lowers it. No stopping videos, no screen flashing, no user interaction. Just quiet magic.
Yes, technically, it uses ADB (Android Debug Bridge) over Wi-Fi, which is a developer tool and not meant for bedtime parenting. But that’s the beauty of it.
Setting Up Your Development Environment
Setting up a development environment and connectivity is crucial before diving into the code. This will ensure you have all the necessary tools and libraries, streamlining the development process.
I use macOS, so all examples in the story will be with this system, but using Windows does not make the process much more difficult compared to MacOS. The only difference is that in the MacOS operating system, Python is already installed, and in Windows, you will have to install Python yourself from here: Windows Python
Here's a more detailed breakdown:
-
Download and Extract Platform Tools:
-
Go to the official Android Developers website:
- Navigate to Android SDK Platform-Tools.
-
Download the SDK Platform Tools:
- Download the latest version for your operating system (Windows, macOS, or Linux).
- Extract the ZIP file: Extract the downloaded ZIP file to a location of your choice (e.g., C:\adb on Windows).
C:\adb
-
-
Add Platform Tools to your System's PATH:
-
Windows:
- Open the "Environment Variables" settings (search for "Environment Variables" in the Start menu).
- Click "Edit the system environment variables".
- Click "Environment Variables".
- In the "System variables" section, find the "Path" variable, select it, and click "Edit".
- Click "New" and add the path to the platform-tools directory (e.g., C:\adb).
-
macOS/Linux:
-
Open your terminal.
-
Add the path to the platform-tools directory to your shell's configuration file (e.g., ~/.bashrc, ~/.zshrc).
For example: export PATH=$PATH:/path/to/platform-tools.
export PATH=$PATH:/usr/local/bin/adb echo $PATH | tr ":" "\n"
In my case, it’ll be something like this:
-
Restart your terminal or source the configuration file (e.g., source ~/.bashrc).
From now on, we will work only in the command line. In my case, it will be the terminal.
-
-
-
Verify ADB Installation:
-
Open a command line interface (CLI):
- Using the Windows Search Bar (Windows OS):
- Click the Start button or the magnifying glass icon in the taskbar.
- Type "cmd" (without quotes) in the search bar.
- Click on the "Command Prompt" result.
- To run as administrator, right-click on "Command Prompt" in the search results and select "Run as administrator".
- Using Spotlight Search (macOS):
- Click the magnifying glass icon in the menu bar (or press Cmd+Space).
- Type "Terminal" and double-click it to open.
- Using the Windows Search Bar (Windows OS):
-
Type adb and press Enter.
adb
-
If adb is installed correctly, you should see the ADB help message.
-
-
Enable USB Debugging on your Android Device:
- Go to "Settings" on your Android device.
- Scroll down and select "About Phone".
- Find "Build Number" and tap it 7 or more times to unlock Developer Options.
- Go back to the main "Settings" page, and now you'll see "Developer Options".
- Select "Developer Options".
- Scroll down to "USB Debugging" and toggle it on.
Setting Up Your Connection
The next step will be connecting your mobile device with your PC. This is a relatively simple step that consists of two parts:
- Wire connection;
- Wireless connection.
Wire Connection:
You should connect your mobile device to your PC using the cable (USB A/USB C or USB A/micro USB, etc.).
After that, you open the terminal and type the following command:
adb devices
For now, we are ready to enable TCP/IP mode with the following command:
adb tcpip 5555
If we are already in the terminal, then we can check the IP address of the mobile device in our Wi-Fi network without looking at the mobile device. Let's run the following command to find out the IP address that we will need later when establishing a wireless connection:
adb -d shell "ip route | awk '/wlan0/ {print \$9}'"
Wireless Connection:
Now that you have your device's IP address, it's time to connect wirelessly. No need for a wired connection anymore. Once you've run adb tcpip 5555
, you can safely unplug the USB cable. The rest of the magic will happen over Wi-Fi.
Make sure both your smartphone and computer are on the same Wi-Fi network. Then, in your terminal, type the following command:
adb connect <DEVICE_IP>:5555
For example, if your device IP is 10.0.0.108
, you’d enter:
adb connect 10.0.0.108:5555
If all goes well, you'll see a message like:
Let’s Talk About the Problem Again
Let’s take a step back and remember what we’re solving. Your child falls asleep peacefully watching a quiet video — maybe a bedtime story or some relaxing sounds. But two hours later? YouTube’s auto-play kicks in, a loud ad blares, or some high-energy cartoon soundtrack wakes them up. They’re groggy. You’re groggy. Everyone starts their day already drained. What we needed was a silent guardian — something invisible and reliable. A system that would gently lower the volume in the background without stopping playback, without flashing annoying pop-ups, and without waking the user. That’s exactly what this script does.
Architecture at a Glance
Here’s a quick diagram that shows how everything connects:
Your computer (running the Python script) connects to the Android device via ADB over Wi-Fi, monitors the volume periodically, and reduces it if needed.
The Script That Does the Magic
The core of the solution is a Python script that communicates with your Android device via ADB over Wi-Fi.
Every 30 seconds, it checks the current music stream volume. If the volume is above 5 (Android typically uses a 15-point scale), the script gently lowers it — one step at a time, with short pauses. If the volume is already 5 or lower, it just keeps watch — waiting silently in case the volume is raised again.
The best part? It respects manual changes. If someone lowers the volume themselves, the script notices and doesn’t interfere. It’s quiet. It’s adaptive. It’s invisible — just like a good bedtime assistant should be.
The Script’s Evolution: From Tiny Hack to Reliable Tool
When I first wrote this script, it was barely a few lines long.
It looked something like this:
import subprocess
import time
import re
def get_stream_volume():
cmd = "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 set_volume(level):
cmd = f"adb shell cmd media_session volume --stream 3 --set {level}"
subprocess.run(cmd, shell=True)
print(f"Volume set to {level}")
def monitor_volume():
while True:
volume = get_stream_volume()
if volume is None:
print("Failed to get volume level. Retrying...")
time.sleep(5)
continue
print(f"Current volume: {volume}")
if volume == 15:
for vol in range(14, 4, -1):
set_volume(vol)
time.sleep(30)
while get_stream_volume() == 5:
print("Volume is at 5, monitoring every 60 seconds...")
time.sleep(60)
if __name__ == "__main__":
monitor_volume()
os.system("adb shell dumpsys audio | grep -i 'streamVolume'")
But soon, reality kicked in. What happens if the device disconnects in the middle of the night? What if ADB throws a timeout? What if the phone isn’t paired? What if the script crashes while everyone’s asleep?
So, the script evolved.
- Sometimes, the device wasn’t connected. So I added
adb connect ip:port
. - Sometimes ADB crashed mid-night. I added exception handling and retries.
- Logging? Yep, added that too.
- File logging and console logging? Of course.
- Volume changes mid-sleep? Now, the script tracks that too — and only intervenes when needed.
- Monitoring frequency? Different intervals for high vs. low volume levels.
- And yes, graceful shutdown
Ctrl + C
.
What started as a few lines of script turned into a tiny watchdog that babysits your phone — so you don’t have to.
import subprocess
import time
import re
import logging
from datetime import datetime
logging.basicConfig(
filename='volume_control.log',
level=logging.INFO,
format='[%(asctime)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
ADB_DEVICE = "10.0.0.108:5555"
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"Reconnected to ADB at {ADB_DEVICE}")
def get_stream_volume():
cmd = "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 {attempt + 1}: Failed to get volume. Retrying after reconnect...")
connect_adb()
time.sleep(delay)
log("All attempts failed. Giving up temporarily.")
return None
def set_volume(level):
cmd = f"adb shell cmd media_session volume --stream 3 --set {level}"
subprocess.run(cmd, shell=True)
log(f"Volume set to {level}, waiting 30 seconds...")
def monitor_volume():
while True:
volume = safe_get_stream_volume()
if volume is None:
log("Initial volume read failed. Retrying in 30 seconds...")
time.sleep(30)
continue
log(f"Current volume: {volume}")
while volume > 5:
set_volume(volume - 1)
time.sleep(30)
volume = safe_get_stream_volume()
if volume is None:
log("Failed to read volume during decreasing.")
break
while True:
volume = safe_get_stream_volume()
if volume is None:
log("Failed to read volume during monitoring.")
time.sleep(30)
break
if volume > 5:
log(f"Volume increased to {volume}, restarting decreasing")
break
log(f"Volume is at {volume}, monitoring every 60 seconds...")
time.sleep(60)
if __name__ == "__main__":
try:
monitor_volume()
except KeyboardInterrupt:
log("Script stopped by user (Ctrl+C)")
except Exception as e:
log(f"Unexpected error: {e}")
finally:
log("Script exited.")
Today, the script is production-grade — and open source. But make sure to change this line ADB_DEVICE = "10.0.0.108:5555" in the script with your IP address from “Setting Up Your Connection”.
Running the Script: Two Easy Options as Well as Cron
You’ve got two main ways to run the script:
- Directly with Python
If you have Python 3 installed, you can just run:
python3 reduce_volume.py
It’ll start immediately and do its job quietly in the background.
- As a Standalone Executable
Want to share it with someone who doesn’t have Python installed?
You can convert the script into a standalone .app
for macOS or .exe
for Windows, using PyInstaller:
pyinstaller --onefile reduce_volume.py
This will create a portable app that can be launched with a double-click — no Python required.
- Even schedule it with a cron job or task scheduler if you're fancy.
One More Thing: Remote ADB Limitations
It’s important to note that ADB over Wi-Fi can be fragile.
Your remote connection will break if:
- The phone reboots.
- The Wi-Fi network changes.
- Developer Mode or USB Debugging gets disabled.
- The device goes too long without ADB activity (some systems auto-kick inactive connections).
- And many others …
So if the script stops working, just repeat the steps from “Setting Up Your Connection”:
-
Connect the mobile device with a wire to your personal computer.
-
Run the command
adb tcpip 5555
adb tcpip 5555
-
And run
adb connect <DEVICE_IP>:5555
adb connect 10.0.0.108:5555
and you’ll be back in business.
Final Thoughts
This hack isn’t about silencing your kid’s fun. It’s about protecting their sleep — and your sanity — from unexpected tech surprises.
This may be a small script, but for my family and me, it was life-changing. No more 2 AM YouTube wakeups. No more cranky mornings. Just peaceful nights and a subtle bit of parenting automation.
- Is it a bit of a hack? Sure.
- Does it work reliably? Absolutely.
- Is it legal? Technically yes, but it operates in a gray zone (ADB access and automated control are not officially supported by Google for end-users).
- But you know what? As long as it helps a tired parent (or even yourself) sleep better — it's worth it.
- It's subtle.
- It's invisible.
- And it works.
Let me know if you want the source code, a one-click setup, or an improved version.
And hey — sleep well. You’ve earned it.
P.S. This solution can be improved and expanded - for example, set up a schedule, adapt to different profiles, track device activity, etc. But even in its basic form, it already solves the main problem: it helps you fall asleep - and sleep peacefully. And yes, if you have a specific request or idea, I will be happy to help you, and at the same time, this will be a topic for another article.