Skip to content

Pocket-Watch/PocketWatch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pocket Watch

Webpage preview

Preface

This is a watch party website. Is it like the others? No.
There are many alternatives, yet the majority of them suffers from the same recurring issues, such as:

  • poor performance (laggy sliders, stuttery animations)
  • poor design choices or silly limitations
  • plenty of bugs and issues which, if reported, are usually ignored, swept aside and never resolved
  • no backwards support (nowadays web developers can barely support the latest browser release)
  • chromium only (because other browser engines don't exist)
  • slow backends written in JS or other scripting languages
  • little to no support for mobile devices (no progress bar, no subtitles, extension-based)
  • glaring synchronization issues across multiple clients
  • lack of server-side support for bypassing CORS

The goals of this project

  • open-source
  • cross-browser compatibility
  • cross-device compatibility (quality experience for mobile users, hence the name - pocket)
  • compatibility with older browsers (4 years back)
  • minimal dependencies
  • no JS frameworks
  • avoiding needlessly complicated or bloated code (let's keep it sane)
  • fighting around browser-specific quirks (lack of standardized slider customization, cues stacking)

Prerequisites

  • Go version 1.22 (released in Feb 2024) or newer (supporting slices and sync.Map)
  • Any major browser version released in 2021 or later (due to CSS features)

Components

Running

Adjust the build script corresponding to your platform by setting -ip and -port arguments. Then execute it:

Windows

build.bat

Linux

./build.sh

PostgreSQL database installation & setup [OPTIONAL]:

  1. Install PostgreSQL
  1. Run setup script setup_database.bat or setup_database.sh
  2. Toggle database with toggle_database.bat or toggle_database.sh

https - How to generate SSL keys

In order to secure incoming and outgoing traffic TLS is crucial

openssl req -newkey rsa:4096  -x509  -sha512  -days 365 -nodes -out certificate.pem -keyout privatekey.pem

Git comes with many preinstalled binaries among which is openssl
On Windows it can be found at Git/usr/bin/openssl.exe where Git is git's root installation directory

Additionally, to have your domain verified you can use a free certificate authority like: https://letsencrypt.org

Custom player

For a watch party to work smoothly it's crucial for the player to be able to distinguish between user-initiated and programmatic playback. Unfortunately the <video> element does not provide a mechanism to accomplish that and player libraries usually don't provide a callback. The most common approach is to try and control the state between events, such as onclick and onplay. Due to synchronization issues between clients and the single-threaded nature of JS it eventually leads to a disorganized codebase. Furthermore, most video players dispatch events by firing events asynchronously, causing them to be out of order.
Proper subtitle support is scarce:

  • no dynamic loading (only static)
  • no customization menus
  • no support for SRT (in-built)
  • no support for shifting

The default web subtitle API doesn't shine either. See WEBVTT API problems.

Prerequisites

Include player stylesheet - player.css

<link rel="stylesheet" href="web/css/player.css">

Include player icons svg - player_icons.svg

let options = new Options();
// The path can be changed in options but it must point to the svg file
options.iconsPath = "resources/pocket_icons.svg"

Optionally preload player script - custom_player.js

<body>
    // Webpage elements
    <script type="module" src="web/js/custom_player.js"></script>
</body>

Import the symbols in Javascript to use them directly

import {Player, Options} from "./js/custom_player.js";

Integrating into a web extension

If you run into security errors related to loading data, expose the resources in manifest.json:

{
  "web_accessible_resources": [
    "player_resources/player_icons.svg"
  ]
}

Prepare and load extension resources:

// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getURL
// For simplicity it's assumed all resources are in one directory
let resources = browser.runtime.getURL("player_resources");

let module = await import(resources + "player.js");
// Access module.Player, module.Options
let playerCssHref = resources + "player.css";
// Add the stylesheet dynamically to a webpage

let options = new module.Options();
options.iconsPath = resources + "player_icons.svg";

API usage examples

Initialize and attach the player to any video element

let videoElement = document.getElementById("cats-video");
let options = new Options();
// Hide the buttons you don't need
options.hideNextButton = true;
options.hideDownloadButton = true;
// Change seeking to 10s
options.seekBy = 10;
// Passing options is optional
let player = new Player(videoElement, options);

Set title, video track and subtitle

player.setTitle("Agent327");
player.setVideoTrack("https://video.blender.org/static/web-videos/264ff760-803e-430e-8d81-15648e904183-720.mp4")
player.setSubtitle("subtitles/Agent327.vtt")

Instant callbacks:

// They're dispatched synchronously
player.onControlsPlay(() => {
    player.setToast("You clicked play.");
})

player.onControlsPause(() => {
    player.setToast("You clicked pause.");
})

player.onControlsSeeked((timestamp) => {
    player.setToast("You seeked to " + timestamp.toFixed(3));
})
// Toasts appear in the top right corner as text, also in fullscreen

Custom subtitle implementation

  • support for parsing SRT and VTT
  • proper cue content sanitization with DOMParser
  • addressed bottlenecks related to shifting, setting and parsing
  • ability to import subtitle files from disk
// Adds a subtitle and doesn't show it
player.addSubtitle("subtitles/Subtitle0.srt");
// Sets a subtitle (shows it)
player.setSubtitle("subtitles/Subtitle1.vtt");
// Shows the subtitle at the given index
player.enableSubtitleTrackAt(0);
// Shifts the currently selected subtitle (either backwards or forwards) by the given amount of seconds 
player.shiftCurrentSubtitleTrackBy(-5);

Web issues rant

RANT.md

About

Work in progress watch party and radio website

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •