### Install Project Dependencies Source: https://github.com/wofwca/jumpcutter/blob/master/README.md Installs the necessary project dependencies using Yarn. This is a prerequisite for building and developing the project. ```bash yarn install ``` -------------------------------- ### Build Commands for Jumpcutter Extension Source: https://context7.com/wofwca/jumpcutter/llms.txt Provides essential bash commands for building the Jumpcutter extension. This includes installing project dependencies using Yarn and updating Git submodules for translation files, which are required for the build process. ```bash # Install dependencies yarn install # Initialize translation files (required) git submodule update --init ``` -------------------------------- ### Get Git Log for Contributors Source: https://github.com/wofwca/jumpcutter/blob/master/docs/release-checklist.md This command retrieves a summary of git commits, including author names and emails, after a specified commit. It's used to identify new contributors for the LICENSE_NOTICES file. The output can be piped to `wc -l` to count the number of unique contributors. ```bash git shortlog --summary --email --after= ``` ```bash git shortlog --summary --email | wc -l ``` -------------------------------- ### Settings Management: Get, Set, and Listen for Changes Source: https://context7.com/wofwca/jumpcutter/llms.txt Provides functions to interact with browser storage for extension settings. It supports retrieving all settings, specific settings, updating settings with partial data, and registering listeners for storage changes. This ensures settings are persistent and reactive. ```typescript // From src/settings/getSettings.ts and src/settings/setSettings.ts import { getSettings, setSettings, addOnStorageChangedListener } from '@/settings'; // Get all settings const allSettings = await getSettings(); console.log(`Silence speed: ${allSettings.silenceSpeedRaw}x`); console.log(`Enabled: ${allSettings.enabled}`); // Get specific settings (more efficient) const { soundedSpeed, volumeThreshold } = await getSettings( 'soundedSpeed', 'volumeThreshold' ); // Update settings await setSettings({ soundedSpeed: 1.25, silenceSpeedRaw: 3.0, volumeThreshold: 0.008 }); // Listen for settings changes const removeListener = addOnStorageChangedListener((changes) => { if (changes.enabled?.newValue !== undefined) { console.log(`Extension ${changes.enabled.newValue ? 'enabled' : 'disabled'}`); } if (changes.soundedSpeed?.newValue) { console.log(`Sounded speed changed to ${changes.soundedSpeed.newValue}x`); } }); // Stop listening removeListener(); ``` -------------------------------- ### Update Manifest Version Source: https://github.com/wofwca/jumpcutter/blob/master/docs/release-checklist.md This command updates the version number in the `src/manifest_base.json` file. It uses `jq` to parse the JSON and set the 'version' field to a new value. Ensure `jq` is installed before running. ```bash jq '.version = ""' src/manifest_base.json > src/manifest_base.json.tmp && mv src/manifest_base.json.tmp src/manifest_base.json ``` -------------------------------- ### Build for Chromium (Chrome, Edge) Source: https://github.com/wofwca/jumpcutter/blob/master/README.md Builds the Jumpcutter extension for Chromium-based browsers like Chrome and Edge. The output will be in the ./dist-chromium directory. ```bash yarn build:chromium ``` -------------------------------- ### Build for Gecko (Firefox) Source: https://github.com/wofwca/jumpcutter/blob/master/README.md Builds the Jumpcutter extension specifically for the Gecko browser engine, typically used by Firefox. The bundled files will be placed in the ./dist-gecko directory. ```bash yarn build:gecko ``` -------------------------------- ### Manage Media Elements with AllMediaElementsController (TypeScript) Source: https://context7.com/wofwca/jumpcutter/llms.txt Introduces the `AllMediaElementsController` class, responsible for orchestrating the management of all media elements on a page. It selects the appropriate silence-skipping controller (Stretching or Cloning) based on user settings and CORS restrictions, and handles dynamic updates and telemetry. ```typescript // From src/entry-points/content/AllMediaElementsController.ts import AllMediaElementsController from './AllMediaElementsController'; // Create the main controller const controller = new AllMediaElementsController(); // When new media elements are discovered, register them const videoElement = document.querySelector('video'); if (videoElement) { controller.onNewMediaElements(videoElement); } // The controller automatically: // - Attaches to playing/unpaused elements // - Switches active element based on user interaction // - Handles settings changes reactively // - Provides telemetry data to the popup UI // Telemetry message structure sent to popup interface TelemetryMessage { sessionTimeSaved: { /* time saved data */ }; lifetimeTimeSaved: { /* cumulative time saved */ }; controllerType: ControllerKind; elementLikelyCorsRestricted: boolean; elementCurrentSrc?: string; createMediaElementSourceCalledForElement: boolean; elementRemainingIntrinsicDuration: number; } ``` -------------------------------- ### Experimental Cloning Algorithm for Precise Seeking Source: https://context7.com/wofwca/jumpcutter/llms.txt Implements a cloning controller that creates a hidden clone of a media element to detect silence ranges ahead of the original. This enables more accurate seeking without audio stretching artifacts. It requires a video element and a settings object, and it provides telemetry data on its operations. ```typescript // From src/entry-points/content/ElementPlaybackControllerCloning/ElementPlaybackControllerCloning.ts import ElementPlaybackControllerCloning from './ElementPlaybackControllerCloning'; // The cloning algorithm works differently: // 1. Creates a hidden clone of the video element // 2. Clone plays ahead to detect silence ranges // 3. Original element seeks past silence or speeds up const videoElement = document.querySelector('video'); const settings = { volumeThreshold: 0.010, // Slightly higher for cloning soundedSpeed: 1.0, silenceSpeed: 2.5, marginBefore: 0.050, // Cloning supports marginBefore naturally marginAfter: 0.030, enableDesyncCorrection: true, isOppositeDay: false // Can skip sounded parts instead }; const controller = new ElementPlaybackControllerCloning( videoElement, settings, (skippedAmount, seekDuration) => { console.log(`Silence-skipping seek: ${skippedAmount}s`); } ); await controller.init(); // The controller automatically: // - Seeks past silence ranges when efficient // - Or speeds up when seek overhead exceeds benefit // - Uses SeekDurationProphet to estimate seek costs // Telemetry includes silence skip information const telemetry = controller.telemetry; if (telemetry.lastSilenceSkippingSeek) { const [from, to] = telemetry.lastSilenceSkippingSeek; console.log(`Last skip: ${from}s -> ${to}s`); } // Handle clone playback errors if (telemetry.clonePlaybackError) { console.warn('Clone element encountered playback error'); } ``` -------------------------------- ### Define Core Extension Settings Interface (TypeScript) Source: https://context7.com/wofwca/jumpcutter/llms.txt Defines the `Settings` interface, outlining all configurable options for the Jump Cutter extension. This includes parameters for volume thresholds, playback speeds, silence detection margins, and the choice between stretching and cloning algorithms. ```typescript // Key settings from src/settings/index.ts interface Settings { // Silence detection threshold (0-1 range, default ~0.006) volumeThreshold: number; // Speed during sounded parts (default: 1) soundedSpeed: number; // Speed during silent parts (relative to soundedSpeed or absolute) silenceSpeedRaw: number; silenceSpeedSpecificationMethod: 'relativeToSoundedSpeed' | 'absolute'; // Time margins for silence detection (in seconds) marginBefore: number; // Look-ahead time before loud parts marginAfter: number; // Delay before switching to silence speed // Whether the extension is active enabled: boolean; // Which algorithm to use experimentalControllerType: ControllerKind.STRETCHING | ControllerKind.CLONING; // Target media types applyTo: 'videoOnly' | 'audioOnly' | 'both'; } ``` -------------------------------- ### Discover Media Elements with MutationObserver (TypeScript) Source: https://context7.com/wofwca/jumpcutter/llms.txt Implements the `watchAllElements` function to monitor the DOM for new video and audio elements. It utilizes `MutationObserver` to detect elements added dynamically after the initial page load and invokes a callback function with newly found media elements. ```typescript // From src/entry-points/content/watchAllElements.ts import watchAllElements from './watchAllElements'; // Watch for video and audio elements on the page const stopWatching = watchAllElements( ['VIDEO', 'AUDIO'], // Tag names to watch (must be uppercase) (newElements) => { // Called with array of newly discovered HTMLMediaElements console.log('Found media elements:', newElements.length); newElements.forEach(element => { console.log(`Media source: ${element.currentSrc}`); console.log(`Duration: ${element.duration}s`); console.log(`Paused: ${element.paused}`); }); } ); // Later: stop watching when done stopWatching(); ``` -------------------------------- ### Popup UI and Chart Source: https://github.com/wofwca/jumpcutter/blob/master/README.md The user interface component, including a chart, for the Jumpcutter extension. This is likely where user interactions and visualizations occur. ```svelte ``` -------------------------------- ### Element Playback Controller Stretching - TypeScript Source: https://context7.com/wofwca/jumpcutter/llms.txt The ElementPlaybackControllerStretching monitors audio output using Web Audio API's AudioWorkletProcessor to adjust video playback rate. It utilizes time-stretching for look-ahead requirements when marginBefore is set. This controller takes video elements and settings as input, provides telemetry, and allows for dynamic setting updates and cleanup. ```typescript // From src/entry-points/content/ElementPlaybackControllerStretching/ElementPlaybackControllerStretching.ts import ElementPlaybackControllerStretching from './ElementPlaybackControllerStretching'; // Controller settings structure interface ControllerSettings { volumeThreshold: number; // e.g., 0.006 soundedSpeed: number; // e.g., 1.0 silenceSpeed: number; // e.g., 2.5 marginBefore: number; // e.g., 0 (seconds) marginAfter: number; // e.g., 0.16 (seconds) enableDesyncCorrection: boolean; isOppositeDay: boolean; // Invert behavior (skip loud parts) } // Create and initialize controller const videoElement = document.querySelector('video'); const settings: ControllerSettings = { volumeThreshold: 0.006, soundedSpeed: 1.0, silenceSpeed: 2.5, marginBefore: 0, marginAfter: 0.16, enableDesyncCorrection: true, isOppositeDay: false }; const controller = new ElementPlaybackControllerStretching( videoElement, settings, (skippedAmount, seekDuration) => { console.log(`Skipped ${skippedAmount}s of silence`); } ); await controller.init(); // Get real-time telemetry const telemetry = controller.telemetry; console.log(`Current volume: ${telemetry.inputVolume}`); console.log(`Playback rate: ${telemetry.lastActualPlaybackRateChange.value}`); console.log(`Speed type: ${telemetry.lastActualPlaybackRateChange.name}`); // Update settings on the fly controller.updateSettingsAndMaybeCreateNewInstance({ ...settings, silenceSpeed: 3.0 // Increase silence speed }); // Cleanup await controller.destroy(); ``` -------------------------------- ### Default Settings Configuration for Jumpcutter Source: https://context7.com/wofwca/jumpcutter/llms.txt Defines the default configuration values for the Jumpcutter extension, including volume thresholds, playback speeds, margins, hotkey configurations, and algorithm-specific settings. It also includes a 'simple slider' mode that adjusts multiple parameters simultaneously. ```typescript // From src/settings/defaultSettings.ts const defaultSettings = { // Volume threshold: lower = more sensitive to silence volumeThreshold: 0.006, // Playback speeds soundedSpeed: 1, silenceSpeedRaw: 2.16, // Based on simpleSlider value silenceSpeedSpecificationMethod: 'relativeToSoundedSpeed', // Margins (time in seconds) marginBefore: 0, // Disabled by default (causes audio stretching) marginAfter: 0.16, // Delay before switching to silence speed // Extension state enabled: true, // Algorithm selection experimentalControllerType: ControllerKind.STRETCHING, // Media targeting applyTo: 'videoOnly', omitMutedElements: true, dontAttachToCrossOriginMedia: true, // Hotkeys enabled by default on desktop enableHotkeys: true, hotkeys: [ { keyCombination: { code: 'KeyX' }, action: HotkeyAction.REWIND, actionArgument: 5 }, { keyCombination: { code: 'KeyC' }, action: HotkeyAction.ADVANCE, actionArgument: 5 }, { keyCombination: { code: 'KeyS' }, action: HotkeyAction.DECREASE_SOUNDED_SPEED, actionArgument: 0.25 }, { keyCombination: { code: 'KeyD' }, action: HotkeyAction.INCREASE_SOUNDED_SPEED, actionArgument: 0.25 }, // ... more hotkeys ], // Algorithm-specific settings algorithmSpecificSettings: { [ControllerKind.STRETCHING]: { volumeThreshold: 0.006, marginBefore: 0, marginAfter: 0.16, }, [ControllerKind.CLONING]: { volumeThreshold: 0.010, marginBefore: 0.050, marginAfter: 0.030, }, }, }; ``` -------------------------------- ### Update Git Submodules Source: https://github.com/wofwca/jumpcutter/blob/master/README.md Updates and initializes git submodules, likely used for fetching localization files. This command is used when the project is managed with Git. ```bash git submodule update --init ``` -------------------------------- ### Element Playback Controller Stretching Source: https://github.com/wofwca/jumpcutter/blob/master/README.md Controls the playback rate of the original HTMLMediaElement. This component is essential for adjusting media playback speed. ```typescript class ElementPlaybackControllerStretching { // ... implementation details ... } ``` -------------------------------- ### Silence Detector Source: https://github.com/wofwca/jumpcutter/blob/master/README.md Utilizes the Web Audio API to detect silence in media playback. It emits SILENCE_END and SILENCE_START events with timestamps. ```typescript class SilenceDetector { // ... implementation details ... } ``` -------------------------------- ### Silence Detector Processor - TypeScript (AudioWorklet) Source: https://context7.com/wofwca/jumpcutter/llms.txt The SilenceDetectorProcessor is an AudioWorkletProcessor that analyzes audio samples in real-time to detect silence. It emits SILENCE_START and SILENCE_END events to the main thread based on volume and duration thresholds. This allows for dynamic adjustment of video playback rates. ```typescript // From src/entry-points/content/SilenceDetector/SilenceDetectorProcessor.ts // This runs in AudioWorkletGlobalScope // Parameter descriptors for the processor const parameterDescriptors = [ { name: 'volumeThreshold', defaultValue: 0.10, minValue: 0, maxValue: 1, automationRate: 'k-rate', }, { name: 'durationThreshold', // Don't act on silence shorter than this minValue: 0, automationRate: 'k-rate', }, ]; // Message types sent to main thread enum SilenceDetectorEventType { SILENCE_START = 0, SILENCE_END = 1, } // Message format: [eventType, timestampInSeconds] type SilenceDetectorMessage = [SilenceDetectorEventType, number]; // Usage from main thread (SilenceDetectorNode.ts) const silenceDetector = new SilenceDetectorNode(audioContext, initialDuration); silenceDetector.volumeThreshold = 0.006; silenceDetector.durationThreshold = 0.16; // marginAfter in real-time silenceDetector.port.onmessage = ({ data }) => { const [eventType, timestamp] = data; if (eventType === SilenceDetectorEventType.SILENCE_END) { // Loud sound detected - switch to sounded speed videoElement.playbackRate = 1.0; } else { // Silence detected - switch to silence speed videoElement.playbackRate = 2.5; } }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.