Changelog

v1.8.1

Track all updates, improvements, and fixes to Based Subtitles.Building in public, one release at a time.

v1.8.1

Latest
Mobile Playback & Camera Fixes
fixed

Camera recording showed black screen on mobile — video element didn't exist in the DOM when the stream was attached; now re-attaches via useEffect when the preview mounts

fixed

Video not playing after scrubbing on mobile — pausing the video on drag start then calling play() on release failed because pointerup on range inputs isn't a trusted gesture on mobile; removed pause/resume entirely

fixed

Video freezing when scrubbing on mobile — was setting videoEl.currentTime on every drag frame, overwhelming the decoder; now only seeks once on pointer release (mediabunny pattern)

fixed

Subtitles showing stale position during seek drag — now calls onTimeUpdate during drag so subtitles and transcript stay in sync with the scrub position

fixed

Video not buffering fully on mobile — added preload="auto" so mobile browsers load the complete video instead of lazy-loading

changed

Replaced <input type="range"> seek bar with custom div-based progress bar using pointer events and setPointerCapture — eliminates all mobile range input quirks and provides reliable touch tracking even when finger drifts off the bar

changed

Progress bar fill and time display update via refs during drag (zero re-renders while scrubbing, Vercel React best practice: useRef for transient values)

changed

Added keyboard support (left/right arrows ±5s) and ARIA slider attributes to custom progress bar for accessibility

changed

Video timeupdate events are ignored during seek drag to prevent the video's stale position from overriding the user's scrub position

v1.8.0

Unified Word Editing & Min Words
added

Per-word emoji size slider — scale each word's emoji independently from 50% to 200% (appears in word style popover when an emoji is set)

added

Compact word style popover on mobile — collapsible icon tabs (Font, Size, Color, FX, Emoji) overlay the video without blocking subtitles or requiring scroll

changed

Word editing standardized to chip bar below video — works in all modes (3D on/off), replacing direct click-on-word in the preview

changed

Word chips restyled with dark background for better visibility

changed

Min words per line lowered from 3 to 1 — allows single-word-at-a-time subtitle display

changed

Emoji size is now per-word instead of global — moved from styling panel to the word style popover

fixed

Emoji overlay size was not applied during video export — now correctly uses per-word emojiScale in all render paths

v1.7.0

Per-Word Emoji Replace & Overlay
added

Per-word emoji replace — click any word and pick an emoji to replace the word text entirely with that emoji

added

Per-word emoji overlay — place an emoji above any word while keeping the text visible underneath

added

Emoji picker integrated into the per-word style popover with search support

added

Emoji replace and overlay render in DOM preview, canvas compositing (3D depth mode), and video export

added

Emoji size scales with the word's font size — enlarging a word also enlarges its emoji

fixed

Word style popover in 3D mode did not update when clicking a different word badge — popover now resets and shows the correct word's settings

added

Branding watermark — toggleable "basedsubs.getbasedapps.com" text in the bottom-left corner, rendered in preview and baked into exported videos

v1.6.0

Letter-by-Letter Text Fade In
added

Letter-by-letter text fade in — characters reveal left-to-right within each word with staggered timing, similar to VEED-style animated captions

added

"Text fade in" toggle in the styling panel — when off, text appears and disappears instantly with no fade effects

added

Letter-by-letter reveal works in DOM preview, canvas compositing (3D depth), and video export

changed

Word and chunk fade effects are now gated behind the text fade in toggle instead of always on

changed

Active word emphasis is now off by default

fixed

Mobile camera starting with black screen — autoPlay not reliable on mobile, now explicitly calls play() after attaching the stream

fixed

Flipping camera showed "camera in use by another app" — the useEffect re-fired openCamera on facingMode change, causing two getUserMedia calls to race for the same device

fixed

Camera defaulting to back camera on some Android devices — now uses exact facingMode constraint instead of a preference hint the browser can ignore

fixed

Mobile styling and edit panels could not be switched directly — had to close one before opening the other. Bottom bar buttons are now toggles with mutual exclusion

fixed

Mobile drawer panels cut off at the bottom — content now fills the full available height down to the navigation bar

fixed

Mobile styling panel couldn't scroll to the last items — scroll area now accounts for the fixed bottom navigation bar

fixed

Letter-by-letter text fade in now works in 3D depth mode — both behind and front text layers support per-character reveal and chunk fade-out

fixed

Mobile transcript panel height was capped at 384px (max-h-96) — removed the cap on mobile so the list fills the drawer

removed

Removed redundant "Subtitles behind person" toggle — its functionality is fully covered by the "Dynamic depth 3D" toggle

v1.5.0

Knockout Text Effect & New Font
added

Knockout text effect — per-word style option that makes the text shape reveal an inverted/negative version of the video behind it

added

Knockout toggle in the word style popover under a new 'Effect' section

added

Knockout renders in DOM preview (mix-blend-mode: difference), canvas compositing (3D depth mode), and video export

added

Lilita One font — thick, bold display font with a magazine-cover aesthetic, great for knockout effects

v1.4.1

Mobile Bug Fixes
fixed

Footer 'Powered by' row no longer overflows on small screens — items wrap and bullet separators hide on mobile

fixed

Video freezing on mobile after transcription — unhandled play() promise rejections from autoplay policy now caught on all play/pause controls

added

Toast notifications for background removal errors — shows a clear message when WebGPU/WASM is unavailable instead of silently failing

v1.4.0

Camera Recording, Custom Player & Bug Fixes
added

Camera recording — record video directly from your camera (front or back) with a 'Record video' button on the landing page

added

Records straight to MP4 using MediaBunny (H.264 + AAC) — no WebM conversion needed

added

Camera flip button to switch between front and back cameras on mobile

added

Review screen after recording with re-record and 'Use this video' options

added

Custom player controls (play/pause, seek bar, time, mute) shown consistently in all modes

added

Click anywhere on the video to play/pause

added

Umami analytics integration

added

Powered by Transformers.js and MediaBunny attribution with logos in the footer

changed

Removed native browser video controls — custom controls prevent subtitles from covering playback buttons

changed

Landing hero tagline updated from 'Free forever' to 'Free'

fixed

Selecting the 500MB model caused a blank screen — base model preload raced with the user's model choice, resolving the wrong download promise

fixed

Added load ID tracking so stale model 'ready' messages from previous downloads can't resolve the wrong promise

fixed

Cancelling the language modal on a fresh upload now returns to the landing page instead of showing a dead-end video screen

fixed

Subtitle text appearing/disappearing no longer causes layout jumps — placeholder space is always reserved

fixed

Word chip bar in compositing mode no longer causes layout shifts between phrases

v1.3.1

3D Depth Export Performance Fix
fixed

Video export with 3D depth enabled was re-running MODNet AI inference on every frame at 30fps (~1,800 calls per minute of video) — now uses pre-computed 5fps mask cache, reducing export time from ~15 minutes to under a minute

fixed

Export with 3D depth consumed ~2GB+ RAM from per-frame 8MB getImageData allocations and data copies to the AI worker — eliminated entirely by using cached masks

v1.3.0

Word Chip Bar & Auto 3D Depth
added

Word chip bar — clickable word buttons appear below the video when 3D depth mode is active, letting you select any word for per-word styling

added

Words with custom style overrides are highlighted with an amber tint in the chip bar

changed

3D depth mode now auto-enables when background removal starts — no extra toggle needed

changed

Per-word selection in 3D/bg-removal mode uses the reliable chip bar instead of canvas click coordinates

fixed

Clicking anywhere on the canvas in 3D mode no longer incorrectly triggers word editing

fixed

Hidden and disabled words can no longer be selected for editing

fixed

Major memory leak in video export — frame pixel data (~8MB) was allocated per-frame instead of reusing an offscreen canvas via GPU blit

fixed

AudioContext not closed on error during export, leaking audio memory

fixed

Reusable canvases and buffers from export were never released after completion, staying in memory indefinitely

changed

Font mapping table (24 entries) extracted to a single module-level constant — was duplicated in 5 functions and recreated per-frame during export

removed

Removed dead hitTestOnly prop from VideoCaption and unused renderDynamicWordToCanvas function

v1.2.0

Per-Word Styling & Preset Preview
added

Per-word custom styling — click any word in the video preview to override its font, size, and color independently

added

Word style popover with font family picker, size multiplier (50%–200%), color picker, and reset button

added

Selected word highlight with yellow outline in the video preview

added

Per-word overrides render correctly in both the live preview and exported video

changed

Preset buttons now render with their actual font — Bangers for Green, Permanent Marker for Gold, Outfit for Subtitle, Bebas Neue for Gamer

changed

Preset buttons show the correct font weight so you can preview the style before applying

v1.1.0

Landing Page Redesign & Performance
added

New landing page with hero section, feature highlights, how-it-works flow, local processing showcase, and call-to-action

added

Full-page drag-and-drop — drop a video anywhere on the landing page to get started

added

Drag-over visual feedback on the dropzone with amber highlight

added

Changelog page at /changelog with version history

added

"Buy me a coffee" floating button

added

Site footer matching getbasedapps design with version link

changed

Redesigned feature cards with playful visual representations — waveform bars, layered text, font samples, language globe

changed

Subtitle style presets now use dynamic fonts (Bangers, Permanent Marker, Bebas Neue, Outfit) instead of generic system fonts

changed

Default subtitle font size changed to Small for a cleaner look

changed

Subtitle styling panel now uses Outfit font with consistent rounded-lg buttons and amber accent colors

changed

Style presets now visible in dynamic (3D) mode for consistent styling

changed

Subtitle preview pinned above the scroll area so it's always visible while adjusting settings

changed

Editor buttons and panels updated to match the new landing page design

fixed

Major memory leak — Whisper model (~1GB) now freed after transcription completes instead of staying in memory

fixed

Major memory leak — background removal model (~500MB-1GB) now freed after processing completes

fixed

Mask data was duplicated in both a ref and React state (~2x memory usage) — removed unused state copy

fixed

Canvas render loop now skips redundant draws when video is paused, saving significant CPU

fixed

ImageData allocation (~8MB) was created every frame at 60fps — now reused across frames

fixed

Temporary canvases in video export now reused across frames instead of recreated per-frame

removed

Removed purple color accents — replaced with amber tones throughout

v1.0.0

Initial Release
added

AI-powered subtitle generation using Whisper.js — runs 100% locally in the browser via WebGPU/WASM

added

Multi-language transcription supporting 100+ languages with selectable Whisper model sizes (tiny, base, small)

added

Background removal with AI person segmentation — processes video frames locally without any uploads

added

Dynamic 3D subtitles — place text behind or in front of people with depth effects

added

Follow-word mode for dynamic subtitles — text tracks the position of the spoken word

added

25+ Google Fonts including Bangers, Montserrat, Bebas Neue, Poppins, Oswald, Anton, Fredoka, Permanent Marker, Pacifico, and more

added

Full subtitle styling controls — font, size, weight, color, background, border, drop shadow, word emphasis

added

Word-by-word and phrase display modes with configurable max words per line

added

Subtitle position control (top, middle, bottom) with adjustable Y positioning for dynamic mode

added

Video export with baked-in subtitles using Mediabunny — downloads MP4 with subtitles permanently rendered

added

Landscape (16:9) and portrait (9:16) aspect ratio modes with zoom toggle for portrait

added

Editable transcript sidebar — click any segment to modify the transcribed text

added

Language selection modal with model size picker before transcription starts

added

Mobile-responsive design with drawer navigation for styling and transcript editing

added

Works offline after first load — all AI models are cached in the browser

added

Free to use — no sign-up, no watermarks, no data collection

The beginning