Firefox Browser Add-ons
  • Extensions
  • Themes
    • for Firefox
    • Dictionaries & Language Packs
    • Other Browser Sites
    • Add-ons for Android
Log in
Preview of Frame Sync - AirPlay

Frame Sync - AirPlay by Garduli

Frame Sync — TuneBlade edition

ExperimentalExperimental
Available on Firefox for Android™Available on Firefox for Android™
0 (0 reviews)0 (0 reviews)
Download Firefox and get the extension
Download file
Scan the QR code to open this extension in Firefox for Android

Extension Metadata

Screenshots
About this extension
Frame Sync — TuneBlade edition
A personal fork of Frame Sync (Fix for Wireless Audio Delay) by maggch, adding
live integration with TuneBlade's HTTP control API.
Upstream Chrome Web Store listing:
https://chromewebstore.google.com/detail/frame-sync-fix-for-wirele/bejofpmoafhoadeofdknblddccfmncji
Upstream source: https://github.com/maggch97/Frame-Sync
Upstream version this fork started from: 1.5 (last updated Nov 2024)
Upstream solves the core problem: when PC audio is streamed to wireless speakers
via TuneBlade, Airfoil or Sonos, the audio arrives late. Frame Sync holds video
frames back by a matching amount so picture and sound line up again. It works on
any site rather than targeting specific ones.
This fork keeps that engine untouched and changes where the delay number comes
from.

The problem this fork solves
Wireless latency is not a fixed property of the speaker. With TuneBlade it is
mostly a property of the streaming mode — RealTime, Normal, Buffered and
Custom(n) each add a different amount of buffer. A single saved delay is correct
in exactly one mode and wrong the moment you switch.
So the delay is no longer one number. It is a set of measurements keyed by
device | mode : buffer, and a background worker keeps the active one in sync
with whatever TuneBlade is actually doing.
What this fork adds
TuneBlade auto-calibration. A background worker polls TuneBlade's HTTP API
while video is playing, builds a profile key from the connected receiver and the
live streaming mode, and swaps the active delay to match. The frame-delay engine
is unchanged — it still reads one value; the worker just decides what it is.
Derived Custom-mode profiles. TuneBlade's Custom buffer adds latency roughly
1:1 in milliseconds, so one measurement at any Custom buffer yields every other
Custom value: offset(B2) ≈ offset(B1) + (B2 − B1). Only the three fixed modes
need real measurements, because their internal buffer sizes are not exposed.
Optional mode forcing. The extension can pin TuneBlade to a known Custom
buffer while video plays and restore the previous mode afterwards, reducing
calibration to a single profile. The original mode is written to storage
before the change, so a worker eviction leaves a restore-to-current no-op
rather than a stuck mode; a stranded mode is recovered on the next worker start.
Goertzel tone detection in the mic measurement page, replacing broadband RMS
onset detection. Energy is measured at the beep frequency only, and each window
is probed at two non-harmonic decoy frequencies — a real tone is far stronger at
the target than the decoys, while broadband noise is roughly equal across all
three. That tonality gate rejects thumps and door slams that would otherwise
register as the beep. A coarse pass locates the block, a short fine pass pins the
onset. Measured to ~3ms against synthetic signals.
Per-machine storage. Settings moved from storage.sync to storage.local.
Audio latency differs per machine and OS, so a synced value let one machine
overwrite another's calibration.
Pin current delay. A hand-tuned value typed into the box can be filed
directly as a profile rather than living only in the active delay field.
Fixes carried in this fork
Calibration wizard seeded from the saved delay. Its step ladder sums to 387ms,
so starting from 0 could never converge on an AirPlay-scale delay.
Mic measurement anchored to the actual recording position at beep time instead
of an assumed pre-beep duration — the AudioWorklet starts several blocks late.
AudioWorklet processor shipped as a real file; extension-page CSP blocks
addModule() on a blob: URL, which threw before any samples were captured.
All DOM built as nodes rather than raw markup. Several status strings
interpolate values returned over HTTP by TuneBlade (device names, mode), which
should never be parsed as markup.

Files
File Role
manifest.json Extension manifest
content.js Frame buffering and canvas overlay (upstream engine)
tuneblade.js Background worker: polling, profiles, mode forcing
popup.html / popup.js Controls, calibration wizard, TuneBlade panel
measure.html / measure.js Mic-based delay measurement
recorder-worklet.js AudioWorklet capture processor
Setup
TuneBlade must expose its HTTP control server on a fixed port —
Settings → Remote Control, or launch with
TuneBlade.exe Silent StartHttpControl Port=54029. Enabling the server and
setting the port are separate steps. Avoid auto: the port changes per start.
In the popup, enable Follow TuneBlade streaming mode and enter the port.
Press Check TuneBlade. It should report the connected receiver and the
live streaming mode.
Calibrate once per streaming mode you use, via the wizard or the mic page.
Custom-mode values are derived from any single Custom measurement.
The extension talks to 127.0.0.1, not localhost — Chrome resolves localhost
to ::1 first and TuneBlade binds IPv4 only.
Firefox notes
Host permissions are optional under Firefox MV3: grant host access from the
add-on's Permissions tab or every request fails. Requires Firefox 140+
(Android 142+). Unsigned add-ons only load temporarily, so permanent installation
needs a signed build. Note that upstream already has an official Firefox port on
AMO, Frame Sync Audio Delay, which does not include the TuneBlade integration.
Companion script
TuneBladeVolume.ahk (AutoHotkey v2) binds the laptop volume keys to TuneBlade's
volume API. Needed because TuneBlade's Direct mode uses WASAPI loopback capture,
which taps the stream before the endpoint volume is applied — so the Windows
master volume has no effect on what is streamed.
Privacy
No data leaves the machine. All state is in storage.local; the only network
traffic is to TuneBlade on the loopback interface.
Credits
Original extension and frame-buffering approach by maggch
(https://github.com/maggch97/Frame-Sync). This fork is a personal build and is
not affiliated with or endorsed by the original author, nor by TuneBlade. Check
the upstream repository for its license terms before redistributing.
Rated 0 by 0 reviewers
Log in to rate this extension
There are no ratings yet

Star rating saved

5
0
4
0
3
0
2
0
1
0
No reviews yet
Permissions and data

Required permissions:

  • Access browser tabs
  • Access your data for all websites

Optional permissions:

  • Access your data for all websites

Data collection:

  • The developer says this extension doesn't require data collection.
Learn more
More information
Add-on Links
  • Support Email
  • Copy add-on ID
Version
2.9
Size
168.15 KB
Last updated
a month ago (Aug 30, 2026)
Related Categories
  • Photos, Music & Videos
License
GNU General Public License v2.0 only
Version History
  • See all versions
Add to collection
Report this add-on
Go to Mozilla's homepage

Add-ons

  • About
  • Firefox Add-ons Blog
  • Extension Workshop
  • Developer Hub
  • Developer Policies
  • Community Blog
  • Forum
  • Report a bug
  • Review Guide

Download

  • Download Firefox
  • Windows
  • macOS
  • iOS
  • Android
  • Linux
  • All

Latest Builds

  • Nightly
  • Beta

Firefox for Business

  • Enterprise

Community

  • Connect
  • Contribute
  • Developer

Follow

  • Instagram
  • YouTube
  • TikTok
  • Bluesky
  • Podcast
  • Privacy
  • Cookies
  • Legal

Except where otherwise noted, content on this site is licensed under the Creative Commons Attribution Share-Alike License v3.0 or any later version. Android is a trademark of Google LLC.