Sports Media Engagement

Build a Watch Party Sync Demo with Shaka Player and PubNub

0 MIN READ • Markus Kohler on Feb 10, 2026
Build a Watch Party with Shaka Player and PubNub

A watch party doesn’t need “video streaming” from PubNub. Your live stream (or VOD) still comes from your CDN via HLS (sometimes shortened to HL) or DASH, using an MPD (MPD) / DASH manifest. PubNub is the real-time layer that keeps everyone in sync with lightweight messages: play, pause, seek, and “I’m at time X” sync beacons.

This tutorial is focused on predictable playback (not jumpy playbacks) and low latency, with a small surface area and clean debugging (debug) when something goes wrong.

This tutorial walks you through a small demo where:

  1. One person is the host

  2. Everyone else is a follower

  3. Followers automatically stay aligned without the player feeling jumpy

Shaka Player PubNub Package

Shaka Player PubNub GitHub

Note: We recently migrated shaka-player to a dev dependency inside the package. You’ll still install what your app needs, but the library build no longer unnecessarily adds extra weight to consumers.

Try the Demo

Want to see it in action before diving into the code? Open the demo in two browser windows (browser support matters here—test in chrome and firefox), click “Become Master” in one, and watch them sync.

Full demo source code: https://github.com/PubNubDevelopers/shaka-watch-party

What you’ll build

  1. A Shaka Player player instance (aka a player instance) running in the browser

  2. A shared “watch party” channel (a PubNub channel)

  3. A sync manager that sends: Play, Pause, Seek and, Periodic Sync Beacons

A scalable real-time sync layer powered by PubNub, so the same pattern can support anything from a small group to large concurrent audiences (since only lightweight sync events are sent, not the video itself)

Watch Party

Prerequisites

Before we start, we will need to sign up for a free PubNub Keyset. We will need to ensure that our stream controller is enabled on our keyset, which should be enabled by default after sign-up. That is it we are good to start implementing this package.

Enable Settings

Next, you will need Node + a basic web app (VITE / Next / plain HTML is fine). This tutorial uses JavaScript, and we’ll reference some common APIs you’ll recognize: Media playback APIs, browser events, and PubNub messaging.

Install Dependencies

Create the Player

We need a video element (videoelement) and initialize Shaka. Shaka also ships a lot of polyfill support (polyfills) for older environments, so we install them up front.

Add Real-time Sync with PubNub

This is where the magic happens. Import the `SyncManager` from `@pubnub/shaka-player` and connect it to your player:

The `SyncManager` wraps your Shaka Player and handles all the real-time communication. You pass in your PubNub keys and the PubNub class itself (this avoids global variable issues with bundlers).

Join a Watch Party Room

A “room” is just a PubNub channel name. Anyone who joins the same room will sync together:

That’s it. Your player is now connected to a shared watch party room. But who’s in control?

Add Host and Follower Controls

Watch parties need a host, someone who controls play, pause, and seeks for everyone. Everyone else follows along automatically.

Yes this is the normal DOM addEventListener pattern (addeventlistener) and it works great with Shaka’s event model too.

When you're the master (host):

  1. Play/pause/seek → instantly syncs to all followers

  2. Periodic sync pulses keep everyone within 0.5 seconds

When you're a follower:

  1. Your playback automatically adjusts to match the host

  2. Drift correction happens silently in the background

Listen for Events (async UX updates)

Want to show who joined, who left, or when the host changes? Subscribe to events from the SyncManager. These callbacks are often async in real apps (e.g., you might fetch avatars or thumbnails (thumbnail) from your backend or use PubNub App Context to store them).

Putting it All Together (HTML + CSS ready)

Below, I have listed a short but complete implementation of the PubNub Shaka Player.

How It Works Under the Hood

When the host presses play:

  1. The host's player fires the play event

  2. SyncManager captures it and publishes a sync command via PubNub

  3. PubNub delivers the message to all followers in ~30ms

  4. Followers' SyncManagers receive the command and call video.play()

  5. Drift correction keeps everyone within 0.5 seconds (configurable)

No WebSockets to manage. No server to deploy. Just install, connect, and sync.

FAQ

Is this “video streaming”?

No—PubNub isn’t carrying video bytes. That’s the point. Your CDN still delivers the HLS/DASH video stream, while PubNub delivers tiny real-time sync events (play/pause/seek + periodic beacons).
This gives you:

  • Predictable scale (message fanout scales cleanly as audiences grow)

  • Lower bandwidth + simpler architecture (no custom sync servers)

  • Low-latency coordination so the watch party feels instant

What about subtitles and localization?

Shaka Player handles subtitle tracks, and your UI can handle locale/locales for labels and messages. PubNub helps on the “social + state” side:

  • Send real-time caption-track changes (e.g., “English CC on”) to everyone

  • Broadcast localization choices per room, or per user (host defaults + follower overrides)

  • Keep UI state consistent across devices without polling

Does this work on Chromecast?

Shaka can integrate with Chromecast patterns depending on your setup; watch party sync is still message-based.

What’s the best way to do debugging?

PubNub makes debugging distributed playback way less painful because you can observe the real-time traffic:

  • Log every sync message type (play/pause/seek/sync) and the timestamps, or use our PubNub Debug Console

  • Detect “who is host” and “who is connected” in real time

  • Add simple connection + presence indicators so users know if they’re synced

Then, validate in Chrome + Firefox to account for browser support differences.

Angular support?

You can use this in Angular apps too, just wrap the setup in a component/service and manage lifecycle cleanly.

What’s Next?

Now that you've got synchronized playback working, here are ways to build a complete watch party experience. The best part is PubNub can handle all of the functionality below.

Add Social Features

Resources:
Live Demo
PubNub Shaka Player
Get free PubNub keys