Skip to content

Commit

Permalink
#28 Implement feature to keep video and audio in sync
Browse files Browse the repository at this point in the history
  • Loading branch information
Bennett Hollstein committed Jul 23, 2021
1 parent 4ad44aa commit 8f4b7be
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"page": "background.html"
},

"browser_action": {
"page_action": {
"default_icon": {
"32": "assets/img/disabled.png"
},
Expand Down
53 changes: 53 additions & 0 deletions src/pages/content/lib/AudioSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import ConfigProvider from "../../shared/configProvider";
import debug from '../../shared/debug';
import SilenceSkipper from './SilenceSkipper';

/**
* Audio Synchronizer
* This will help to keep Audio and Video in sync on Chromium based browsers
*
* Related: https://github.com/vantezzen/skip-silence/issues/28
*/
export default class AudioSync {
// Parent skipper
skipper : SilenceSkipper;

// Is the loop currently running
isActive = false;

/**
* Set up the class
*
* @param config Config to use
*/
constructor(skipper : SilenceSkipper) {
this.skipper = skipper;
this.sync = this.sync.bind(this);

this.skipper.config.onUpdate(() => {
if (this.skipper.config.get('keep_audio_sync') && !this.isActive) {
// Start the loop
this.sync();
}
});

this.sync();
}

/**
* Synchronize the audio and video of the media element
*/
private sync() {
if (this.skipper.config.get('keep_audio_sync')) {
this.isActive = true;
this.skipper.element.currentTime = this.skipper.element.currentTime;
debug("AudioSync: Synced audio");

setTimeout(this.sync, 5000);
} else {
debug('AudioSync: Stopping because option was disabled');

this.isActive = false;
}
}
}
3 changes: 3 additions & 0 deletions src/pages/content/lib/SilenceSkipper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MediaElement } from '../../shared/types';
import debug from '../../shared/debug';
import ConfigProvider from '../../shared/configProvider';
import DynamicThresholdCalculator from "./DynamicThresholdCalculator";
import AudioSync from "./AudioSync";

/**
* Silence Skipper: This class is doing the job of actually inspecting media elements and
Expand Down Expand Up @@ -34,6 +35,7 @@ export default class SilenceSkipper {

// Dependencies
dynamicThresholdCalculator : DynamicThresholdCalculator;
audioSync : AudioSync;

/**
* Add silence skipper to element
Expand All @@ -54,6 +56,7 @@ export default class SilenceSkipper {
}
}
this.dynamicThresholdCalculator = new DynamicThresholdCalculator(config);
this.audioSync = new AudioSync(this);

// Attach our config listener
this.config.onUpdate(() => this._onConfigUpdate());
Expand Down
24 changes: 23 additions & 1 deletion src/pages/popup/Popup.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { ChangeEvent, Component } from 'react';
import { Power, Play, FastForward, BarChart2, Volume2, Columns, Volume, Circle, PieChart } from 'react-feather';
import { Power, Play, FastForward, BarChart2, Volume2, Columns, Volume, Circle, PieChart, Speaker } from 'react-feather';
import { CSSTransition } from 'react-transition-group';
import { browser } from 'webextension-polyfill-ts';
import './Popup.css';
Expand All @@ -20,6 +20,8 @@ import verifyLicense from '../shared/license';
import PlusInfo from './components/plusInfo';
import HelpModal from './components/helpModal';

const isChromium = navigator.userAgent.includes("Chrome");

class Popup extends Component {
config : ConfigProvider;
isComponentMounted = false;
Expand Down Expand Up @@ -280,6 +282,26 @@ class Popup extends Component {
)}
/>

{isChromium && (
<Switch
name="keep_audio_sync"
label={(<><Speaker className="setting-icon" /> Keep Audio in Sync{!this.state.isPlus ? ' ★' : ''}</>)}
config={this.config}
plusDisabled={!this.state.isPlus}
openPlusPopup={() => this.showPlusPopup()}
info={(
<HelpModal>
<h2>Keep Audio in Sync</h2>
<p>
Chrome and Browsers that base on Chromium (e.g. Edge) currently have a bug that will result in audio and video getting out of sync when changing the speed often.<br />
As "Skip Silence" will change the video speed often, you might experience this issue.<br />
When this setting is activated, Skip Silence will try to fix this issue by periodically putting them back into sync.
</p>
</HelpModal>
)}
/>
)}

<Switch
name="is_bar_icon_enabled"
label={(<><Circle className="setting-icon" /> Enable Command Bar Icon</>)}
Expand Down
3 changes: 2 additions & 1 deletion src/pages/shared/components/switch.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { ChangeEvent } from 'react';
import defaultConfig from '../config';
import ConfigProvider from '../configProvider';

import "./switch.scss";

interface SwitchProps {
label: string | React.ReactNode,
name: "enabled" | "mute_silence" | "is_bar_icon_enabled" | "allow_analytics" | "dynamic_silence_threshold",
name: keyof typeof defaultConfig,
config: ConfigProvider,
plusDisabled?: boolean,
openPlusPopup?: () => void,
Expand Down
2 changes: 2 additions & 0 deletions src/pages/shared/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ const defaultConfig = {
silence_speed: 3,
silence_speed_is_custom: false,

// Other features
mute_silence: false,
keep_audio_sync: false,

// Command Bar
is_bar_icon_enabled: true,
Expand Down
1 change: 1 addition & 0 deletions src/pages/shared/configProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const storedKeys : (keyof typeof defaultConfig)[] = [
"silence_speed_is_custom",

"mute_silence",
"keep_audio_sync",

"is_bar_icon_enabled",
"is_bar_collapsed",
Expand Down

0 comments on commit 8f4b7be

Please sign in to comment.