πšπš’πšŠπš— πŸ΄β€β˜ οΈπŸŽΆ's avatar
πšπš’πšŠπš— πŸ΄β€β˜ οΈπŸŽΆ
ryan@spatia-arcana.com
npub1m64h...uaks
Play Flappy Nostrich @ flappy-nostrich.vercel.app/ Est. 776032 πŸ’œπŸ«‚πŸ€™
πšπš’πšŠπš— πŸ΄β€β˜ οΈπŸŽΆ's avatar
Ryan 1 week ago
Hmm. The same signaling events I use to do live playlists could let me remote control desktop playback on #gruuv from my phone πŸ€”
πšπš’πšŠπš— πŸ΄β€β˜ οΈπŸŽΆ's avatar
Ryan 1 week ago
#gruuv - testing again πŸ˜† - yesterday's test of live queue gave me a lot of good feedback for the clanker. I think this update is fairly stable, and they should work. Playback sync & view bugs have been fixed, theoretically. - something something totally refactor app.tsx, so many lines of code πŸ€·β€β™‚οΈ
πšπš’πšŠπš— πŸ΄β€β˜ οΈπŸŽΆ's avatar
Ryan 1 week ago
GM Nostr, I'm up early Sunday. Mosha is still resting πŸΆπŸ’€πŸ€«
πšπš’πšŠπš— πŸ΄β€β˜ οΈπŸŽΆ's avatar
Ryan 1 week ago
Draft Spec: Live Music Rooms (Host-Authoritative) This specification defines a set of events for hosting real-time, synchronized music listening rooms over Nostr. It relies on a host-authoritative model where a single DJ broadcasts their queue and playback state, and guests synchronize their local audio players. Rooms are identified by a unique d tag (typically the host's pubkey) and categorized using the t tag gruuv-live-room. 1. Live Room Queue (Kind: 32401) A replaceable event that represents the current playlist/queue of the live room. The host publishes this whenever the track list is modified (tracks added, removed, or reordered). * Kind: 32401 * Tags: * d: The unique Room ID (Recommended: the host's pubkey). * t: gruuv-live-room * title: (Optional) The display name of the station. * Content: A stringified JSON array of track objects. Content Schema: 1 [ 2 { 3 "id": "<string> (Original kind 36787 event ID or fallback ID)", 4 "title": "<string>", 5 "artist": "<string>", 6 "album": "<string>", 7 "url": "<string> (Direct media URL)", 8 "sha256": "<string> (Optional, media hash)", 9 "image": "<string> (Optional, album art URL)", 10 "duration": "<number> (Seconds)", 11 "pubkey": "<string> (Original uploader's pubkey)" 12 } 13 ] 2. Live Playback State (Kind: 32402) A replaceable event that acts as the real-time synchronization heartbeat. The host publishes this immediately on any playback change (play, pause, seek, track skip) and also on a regular heartbeat interval (e.g., every 30 seconds). * Kind: 32402 * Tags: * d: The Room ID (must match the 32401 d tag). * t: gruuv-live-room * Content: A stringified JSON object representing the exact playhead state. Content Schema: 1 { 2 "sha256": "<string> (ID or SHA256 of the currently playing track from the queue)", 3 "position": "<number> (Playhead position in seconds at the time of the event)", 4 "status": "<string> ('PLAYING' | 'PAUSED')", 5 "createdAt": "<number> (Unix timestamp of when the state was captured)" 6 } Client Sync Logic: When a guest receives this event, if status is PLAYING, they should calculate the corrected playhead position by adding the elapsed time since the event's created_at timestamp: correctedPosition = position + (now - created_at). 3. Live Room Chat (Kind: 22402) An ephemeral event representing a chat message sent by any user within the context of the live room. * Kind: 22402 (Ephemeral, does not need to be stored long-term by relays). * Tags: * d: The Room ID (must match the station's d tag). * t: gruuv-live-room * Content: <string> The plaintext chat message. --- Subscription Example To discover live rooms and listen to their events, clients should use the following filter: 1 { 2 "kinds": [32401, 32402, 22402], 3 "#t": ["gruuv-live-room"], 4 "limit": 100 5 } Note: You can easily restrict the subscription to a specific room by adding #d: ["<room_id>"] to the filter.
πšπš’πšŠπš— πŸ΄β€β˜ οΈπŸŽΆ's avatar
Ryan 1 week ago
Good morning. My plan for the day is black coffee, dog walks, and adding live play queues with ephemeral chat to gruuv. Have a good day 🫑
↑