A cross-platform Python application that receives gesture commands from an ESP microcontroller via serial communication and controls media playback and volume on your computer.
- 🎵 Play/Pause - Control media playback
- ⏭️ Next/Previous Track - Skip between tracks
- 🔊 Volume Up/Down - Adjust system volume
- 🖥️ Cross-platform - Works on macOS, Linux, and Windows
- 🔌 Auto-detection - Automatically detects serial port and OS
- 🎧 Universal Media Control - Works with ANY media player (Spotify, Apple Music, YouTube, VLC, etc.)
| Command | Action |
|---|---|
PLAY_PAUSE |
Toggle play/pause |
NEXT |
Next track |
PREV |
Previous track |
VOL_UP |
Increase volume |
VOL_DOWN |
Decrease volume |
python3 -m venv venv
source venv/bin/activate # On macOS/Linux
# OR
venv\Scripts\activate # On Windowspip install -r requirements.txtThe pyobjc-framework-Quartz package is automatically installed from requirements.txt. This enables universal media control that works with any media player.
- Go to System Settings → Privacy & Security → Accessibility
- Add your terminal app (Terminal.app, iTerm, or VS Code) to the list
- Enable the toggle for the app
- Restart the terminal after granting permissions
- Media Control: Uses system media keys via Quartz framework (works with ANY app)
- Volume Control: Uses native AppleScript
- Fallback: If Quartz fails, falls back to direct AppleScript control of Music/Spotify
Install the following tools for media and volume control:
# For media control (highly recommended)
sudo apt install playerctl
# For volume control (usually one of these is pre-installed)
sudo apt install pulseaudio-utils # provides pactl (PulseAudio)
# OR
sudo apt install alsa-utils # provides amixer (ALSA)- Media Control: Uses
playerctl(preferred) or D-Bus directly - Volume Control: Uses
pactl(PulseAudio) oramixer(ALSA)
No additional setup required - uses pyautogui for media key simulation.
- Media Control: Uses
pyautoguito simulate media keys - Volume Control: Uses
pyautoguito simulate volume keys
Connect your ESP microcontroller to your computer via USB.
macOS:
ls /dev/tty.*Linux:
ls /dev/ttyUSB* /dev/ttyACM*Windows: Check Device Manager for COM port number.
python pyserial_media.pyThe script will:
- Display detected OS and available tools
- Auto-detect your serial port
- Connect and listen for gesture commands
Example output:
==================================================
SYSTEM DETECTION
==================================================
OS: macOS (using Quartz for universal media control)
Volume control: AppleScript
==================================================
Auto-detected serial port: /dev/tty.usbserial-0001
Attempting to connect to /dev/tty.usbserial-0001...
Successfully connected to /dev/tty.usbserial-0001.
Listening for gestures. Press Ctrl+C to exit.
If auto-detection doesn't work, edit pyserial_media.py and modify the fallback port in the get_serial_port() function:
if sys.platform == 'darwin': # macOS
return '/dev/tty.usbserial-XXXX' # Replace with your port
elif sys.platform.startswith('linux'):
return '/dev/ttyUSB0' # Or /dev/ttyACM0
else: # Windows
return 'COM3' # Replace with your COM port- Ensure Accessibility permissions are granted to your terminal
- Restart your terminal after granting permissions
- Make sure
pyobjc-framework-Quartzis installed:pip install pyobjc-framework-Quartz
- Have a media player open and playing
Volume control uses AppleScript and should work out of the box. If not working:
- Try running manually:
osascript -e 'set volume output volume 50'
Add your user to the dialout group:
sudo usermod -a -G dialout $USERThen log out and log back in.
- Verify
playerctlis installed:playerctl --version - Check if a player is detected:
playerctl status - List available players:
playerctl -l
- Check if PulseAudio is running:
pactl info - Or verify ALSA is available:
amixer
- Ensure
pyautoguiis installed - Try running as administrator
- Ensure the ESP device is connected
- Check if the device appears in the port list
- Try unplugging and replugging the device
- Check USB cable (some cables are charge-only)
| Package | Purpose | Platform |
|---|---|---|
pyserial |
Serial communication | All |
pyautogui |
Media key simulation | Windows |
pyobjc-framework-Quartz |
System media keys | macOS only |
| Package | Purpose |
|---|---|
playerctl |
Media control (recommended) |
pulseaudio-utils |
Volume control (pactl) |
alsa-utils |
Volume control (amixer) |
- ESP8266 or ESP32 microcontroller
- IMU sensor (for gesture detection)
- USB cable for serial communication
chotubot/
├── pyserial_media.py # Main Python script
├── requirements.txt # Python dependencies
├── README.md # This file
├── imu_songs/ # Arduino sketch for IMU
│ └── imu_songs.ino
└── songs_animation/ # Arduino sketch with animations
├── songs_animation.ino
└── logo.h
- Apple Music
- Spotify
- YouTube (in browser)
- VLC
- Any app that responds to media keys
- Spotify
- VLC
- Rhythmbox
- Any MPRIS-compatible player
- Spotify
- Windows Media Player
- Any app that responds to media keys
MIT License
http://arduino.esp8266.com/stable/package_esp8266com_index.json