Synching Up Play/Pause: Ironing Out the Details

Dani Meyer
Building Couch Potato
4 min readAug 3, 2020

As of our last installment, which discusses how we built our Chrome extension that lets friends watch shows together on Hulu, we had synchronized play/pause working, but there were still some kinks that needed to be worked out. One of the biggest ones was to prevent play/pause from being inverse on different computers, but that wasn’t the only one.

Our celebration at getting play/pause to work was short-lived, as we quickly realized that all users on a couch had to coordinate whether they were playing the show or had it paused when they joined the couch so that someone hitting play didn’t accidentally pause someone else’s screen. It’s definitely not an ideal user experience!

To account for that, we started by grabbing the status of a show (playing or paused) from an attribute on the play/pause button and putting it in localStorage, saving ‘true’ if the status was playing and ‘false’ if it was paused. We had initially hoped to use booleans, but realized when we were debugging that localStorage can only handle strings, so we changed our booleans to strings but stuck with the true/false terminology.

Then, depending on whether the show was currently playing or paused when the play/pause button was clicked by a user, we set up an if/else statement in our event listener on the button that used different API routes for the cross-domain fetch request, which generated different messages to go through our web sockets and show up in the chat that were tailored to whether someone played or paused their videos (the message previously only said that a user played/paused their video; it didn’t indicate which).

Both API routes sent messages via the same socket, which sent a postMessage to the Hulu Window indicating that we wanted the Window to handle the play/pause action, whether to play or pause the show, and which user generated the click.

On the Window, we took advantage of the huluID mentioned in our previous post to determine whether that user clicked on the play/pause button. If they did not, we created a second if/else statement to check what the show is currently doing and whether or not it needs to be updated.

For instance, if Caitlin presses play, but June’s video is already playing, our code sees that June didn’t press the button, but that the status on June’s localStorage already matches the status passed along from Caitlin’s play/pause loop, and it allows June’s video to continue playing. Then, if Caitlin pauses the show later to go get more popcorn, the code will see that June’s video status no longer matches the status sent out by Caitlin’s click, and it will pause her screen as well. As such, it doesn’t matter whether or not users have their playing and pausing lined up when they join a couch; the extension tracks what action each user takes and ensures that all of the users align with it.

While splitting up the play and pause cross-domain fetch requests and API routes made it easier for us to keep playing and pausing shows consistent across all users on a particular couch, it was also a great opportunity to add a timestamp to our message in the chat. This was an especially important feature as we weren’t able to figure out how to share a link and have it automatically take new users to the right part of a show, like some similar extension do. While having users coordinate it themselves isn’t ideal, adding a timestamp to the messages made it a lot easier.

Doing so was largely a matter of grabbing the time stamp off of the control bar and sending it along through the cross-domain fetch request as part of the URL. The Couch Potato backend then used that information as part of the message it sent through the sockets to let users know someone played or paused their video.

Photo by Renato Trentin on Unsplash

As a result of all of our work getting the play/pause functionality to sync up, we went from no synchronization, to synchronization with a simple message saying something like “Grace played/paused their video,” to “Grace paused their video at 4:17.”

It took a lot of fiddling, but in the end, we were able to add a significant feature to our extension and make it as functional as possible with the limitations we had. And it put our extension in a place where we felt comfortable putting it up on the Chrome store (we followed this tutorial in order to do it, though the documentation is also helpful).

Of course, having our extension out there in the world was (and still is!) terrifying. We were afraid our extension would break once others started using it, and it turns out that that’s exactly what happened! In fact, it’s happened enough since putting our extension in the Chrome store that our next (and second to last) blog post is about how we’ve been maintaining our code. Stay tuned!

Interested in learning more about Couch Potato? Start this blog series from the beginning! And don’t forget to download Couch Potato from the Chrome store so you can start watching shows with friends now!

--

--

Dani Meyer
Building Couch Potato

Grace Hopper grad and former business development profesional. Please talk books, history, and puns with me!