Music is better together. That sounds obvious, but most music apps treat listening as a solitary activity. You put on headphones. You hit play. You tune out the world. What if instead, you could share the exact same playback experience with a friend — same track, same timestamp, same controls — regardless of which device you are on?
That is what Listen Together does in SongWalk.
The Idea: Google Docs for Music
Think of it like a shared document. Everyone connected to the same library can press play, pause, next, or seek — and every other listener mirrors the action. There is no host. Whoever presses something first wins. The protocol is tiny because you are not streaming audio — you are streaming intent.
How It Works
Under the hood, Listen Together uses Flask-SocketIO with WebSocket rooms. Each library gets its own sync room. When you tap the Listen Together button, you join the room. When a friend scans the QR code or clicks the share link, they join too.
The protocol is dead simple. Every action is a JSON message:
{"action": "play", "position": 52.3, "track_id": "abc123"}
{"action": "pause", "position": 61.4}
{"action": "seek", "position": 120.3}
{"action": "next", "track_id": "def456"}
The server broadcasts each message to everyone else in the room. Clients ignore their own messages (via peer_id). A 500ms ignore window after each local action prevents echo loops.
Auto-Resync Keeps Everyone Locked
Every 5 seconds, each client sends its current state: which track, what position, and whether it is playing. If two clients are more than 300ms apart, the lagging one silently seeks to catch up. The user never notices. It just works.
Server-Side Peer Tracking
The sync backend maintains a dictionary of rooms and connected peers. When someone joins, everyone gets the full peer list — including the new person. When someone disconnects, the room updates. The dialog shows exactly who is listening together in real time.
Built for Real-World Use
Originally, SongWalk ran on Waitress (a production WSGI server). But Waitress does not support WebSocket. Switching to eventlet with SocketIO’s built-in server gave us WebSocket support on the same port without adding complexity. The Socket.IO client falls back to long-polling if WebSocket is unavailable.
The result: two people, two devices, one shared listening experience. Open the library, tap Listen Together, scan the QR code on your friend’s phone, and you are synced.
Try Listen Together on SongWalk with a friend.
Leave a Reply