Contribute
Presto
Playback speed control for every video on the web, not just YouTube.
- JavaScript
- WebExtensions
- Manifest V3
No tagged issues yet. Open one!
Presto is one dependency-free content script with no build step and no package.json, so you can understand the whole extension in an afternoon. Issues and pull requests are welcome.
The three hard problems
Most of Presto's code exists because naive speed controllers break in three ways:
- Players reset the speed. Adaptive players reassign
playbackRateon quality switches, ads and source changes, so every media element gets a guardedratechangelistener that puts your speed back. - Every frame is isolated. Each iframe runs its own copy of the script. Speed changes are relayed to the top frame, which owns the state and broadcasts it down the frame tree.
- Sites bind the same keys. The key listener runs on
windowin the capture phase so it wins against player shortcuts, and it stays out of the way while you type in a field.
The control is drawn over each video instead of inside the player's markup, so it survives sites that rebuild their controls.
Set up
git clone https://github.com/SUD747/presto && cd presto
node test/unit.js
python3 -m http.server -d test 8000 # test page at http://localhost:8000/page.htmlThen run the extension in a throwaway browser profile that reloads whenever a file changes:
npx web-ext run # Firefox
npx web-ext run -t chromium # Chrome
npx web-ext run -u http://localhost:8000/page.html # and open the test pageIf you load it by hand instead, refreshing the page won't pick up edits to src/content.js. Reload the extension first.
Where things live
src/content.js: everything that happens on the page. Keep it a single file with no dependencies.src/popup.*: the toolbar panel.src/steps.jsholds the step sizes both of them share.test/unit.js: speed and step arithmetic, extracted fromcontent.jsitself so the test can't drift from the code.test/page.html: a manual harness with a plain video, one in a shadow root, one in an iframe, a text field, and a video added after load.
Before you open a PR
- Add a case to
test/unit.jsif the change can be tested without a browser, or totest/page.htmlif it can't. - Keep Mozilla's linter clean:
npx web-ext lint --self-hostedshould report zero errors and zero warnings. - Say which real sites you tested on. Ad breaks and quality switches only show up there.
Found a security issue? Report it privately as described in SECURITY.md, not in a public issue.
Want every detail? Read the full CONTRIBUTING.md on GitHub
Not a coder, or short on time? You can support Presto another way: Buy me a coffee