Following the successful launch of our managed wallet and membership token functionality, I started to think about the kinds of exclusive online events our artists could hold for their community members. In the music industry, listening parties are a time-honoured tradition in which new music is previewed for fans in an intimate setting before being released publicly. In addition to giving attendees “you were there at the start” bragging rights, these events foster a sense of community around a release and can help generate valuable organic buzz in music culture’s increasingly-congested attention economy.
There are lots of options for holding virtual listening parties, and we spent some time researching different approaches. Twitter Spaces (X Spaces?) have been a simple go-to live audio solution for many artists, though recent turmoil at the company puts their ongoing reliability into question. Video live streaming solutions abound (YouTube, Twitch, TikTok, Instagram, etc...) but naturally require one to be prepared to be seen as well as heard. All of these services are relatively free-form, which might be what some artists are after, but we wanted to see if there was a more structured, purpose-built solution out there. After some further digging, we came across Lee Martin’s impressive listeningparty.com project, which appealed to us on a number of fronts, and appeared to be taking customers on board.
Lee is an extraordinarily prolific and busy developer, having built some of the more imaginative and effective music marketing campaigns in the industry. A couple of outreach attempts went unanswered however, leading us to conclude the listening party project is currently dormant, but thankfully Lee had published a detailed blog post describing his design philosophy and the application build-out, giving us the basic building blocks for rolling our own solution.
Requirements
As a member-only feature on web3-enabled artist sites, our listening party would be token-gated, requiring attendees to have already claimed a membership token to participate. Once admitted to the party, guests would see a prompt to save a second “attendance” token and be urged to both pre-save the track on Spotify and contribute to the live chat during the duration of the event. We wanted a countdown clock on screen prior to the event start, and another countdown clock once it finished, indicating how much time was left until the song went live on streaming services. In between, a simple web audio player would loop the track on repeat.
If possible, we wanted to avoid the extra step of running an external one-to-many live stream, but attendees should feel like they were all listening to the track in unison; once set up, our aim was for the party to run itself without any intervention from the host(s), leaving them free to focus on fan interaction via the live chat feed. Design-wise, we wanted to follow Lee’s simple intuitive layout which included an attract-loop video above the audio player to keep things feeling lively and dynamic. And we also wanted to display the number of current listeners while the party was live.
The Build
Adam Hunter once again took the reins on the build. As with our web3 “Welcome” page, the listening party would be configured in advance on our customer dashboard and then published as a member-gated post on the artist’s Ghost site. We created a dashboard form with all required fields, including date pickers and upload widgets for the audio and video assets. Submitting the form triggers the creation of the post, via the create post function in Ghost’s admin API, and a block of embeddable JavaScript with all the values is passed into this new page, which is left in draft mode. On the Ghost side, Adam set up a custom page template just for listening parties, which contains further code to manage the audio player and also render the page with the style and layout that we were after, including a half-height hero header and a comments iframe on the right side. Of course, rendering the page is only half the battle, significantly more work was required to get the Ghost’s native audio player and commenting system to work as we intended.
Audio Adventures
There were good reasons to try and adapt Ghost’s native audio player to our use case – we could rely on the system’s media uploading and storage functionality for one thing – but it would need to be heavily customized both visually and functionally. On web browsers, audio playback has to be triggered by a user click event somewhere on the page and normally that isn’t a problem – think of a standard ‘play’ button for instance – but in our case, we wanted the illusion of an in-progress live stream that attendees would join. On Lee’s listening party demo page there is no play button on the player, just a mute/unmute button. Upon closer examination, we realized that this toggle was functioning as a play button, generating the required click action on the part of the user. But the audio was already playing as evidenced by the time counter, and playback was joined midstream, so what exactly was going on here?
The answer lay in a second post on Lee Martin’s dev blog in a section called Faux Livestream. In that post, about an ingenious Future Islands “unlock” campaign, he describes how he simulated a live stream by using a code snippet that calculates the playback position of a track based on a given start time and the current time. Clicking ‘unmute’ would trigger the calculation and send the playhead to the appropriate point in the audio timeline. Ingenious! Armed with this insight, Adam created a custom listening party add-on for Ghost’s Koenig editor to handle audio playback and then merged the time-calculation code into the page template where it would execute and perform the seek operation on an unmute press. He also added code to handle looping, the numerical counter, as well as the pre- and post-countdown clocks. Finally, we added the necessary image assets and CSS styling to give the player the visual look and feel desired. At last, we had the audio playback functionality we wanted.
Live Chat
After years of politely refusing to integrate native commenting into their platform, the Ghost team finally relented and introduced the feature in August 2022, dramatically improving on what third-party commenting solutions had offered previously. It was trivial for us to enable commenting and place the comment widget on the page, but a quick test revealed that it lacked one must-have feature: real-time updating. We could not reasonably expect our users to continually press refresh to see the latest comments, and given everything happening on the page, it would have been prohibitively disruptive.
Adam’s first crack at the problem was to try polling the Ghost server at set intervals to update the feed in the user’s browser. This worked in a hacky kind of way, but it was not a scalable solution - at a certain point, the load on the server from multiple polling requests would bring it crashing down. While we were not likely in immediate danger of that happening, we wanted the insurance of a more robust solution, and for that we’d need to employ a socket server.
We took a look at Amazon’s WebSocket service since it would have allowed us to keep things under one technical roof, but the configuration of the service appeared overly complex and time-consuming compared to more user-friendly offerings like Pusher, which Adam had used in the past. Pusher’s free tier allowed for 100 concurrent sessions and required much less custom coding so we elected to go that route. If we hit the limit, then Pusher Pro at $99/month would give us 2000 concurrent sessions, and still likely be more cost-effective than building an AWS solution from scratch. A second advantage of Pusher was that it easily allowed us to add the online count feature (”28 Listening Now”) to the party post. For the moment we bundled that code alongside the comments module, making them interdependent.
We were close to being done, but two further wrinkles remained. The first was that there was no webhook emitted for when a new comment was submitted, perhaps because commenting was relatively new and the Ghost team simply hadn’t had time to implement one. Adam was able to work around this limitation, in part by following the suggestions in this forum post, and after a bit of trial and error, we got things working with a custom handler.
The final issue related to display and styling, things like setting a max-height value so comments didn’t scroll endlessly down the page, adding appropriate padding around elements, disabling threaded replies, and things of that nature. Some were a bit finicky, but all were eventually surmountable.
The Attendance Token
The layout of the party post didn’t leave a lot of room for the display of the attendance token, so we elected to place it in a modal dialog, with the code to render it bundled into the button set at the bottom of the page. As with the membership token, the 3D attendance card was configured on the client dashboard and given a distinctive saw-tooth edge along the top and bottom to echo the look of a perforated physical ticket. The claim action was set to active for the duration of the party, and limited to one token per attendee.
The Inaugural Party
On July 19th, 2023 New Friends held a listening party to preview their upcoming release “Sad Sugar”. The event went off without a hitch, with 41 attendees claiming a token and 375 comments posted in the chat feed. You can watch a one-minute video distillation of that party below, and/or you can visit an ongoing demo party page on this site to play around with the functionality. We’re pleased to have this new fan engagement feature in our web3 toolbox and look forward to deploying it to other artist communities in the months ahead.