Giter Site home page Giter Site logo

wofwca / jumpcutter Goto Github PK

View Code? Open in Web Editor NEW
281.0 7.0 11.0 6.13 MB

⏩ Fast-forwards long pauses between sentences — watch lectures ~1.5x faster (browser extension)

Home Page: https://chrome.google.com/webstore/detail/jump-cutter/lmppdpldfpfdlipofacekcfleacbbncp

License: GNU Affero General Public License v3.0

JavaScript 2.78% CSS 0.32% HTML 0.24% Svelte 21.79% TypeScript 74.42% Python 0.37% Shell 0.07%
chrome-extension youtube video productivity audio audio-processing web-audio-api firefox-addon browser-extension firefox-extension

jumpcutter's People

Contributors

an40uss avatar comradekingu avatar hychanbn1009 avatar jakubiakdev avatar wofwca avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

jumpcutter's Issues

Nodejs Version of jumpcutter

The extension helped me a lot. So i want to request you a nodejs version of this, that can run on terminal with local vídeos. Thank you WofWca.

improvement: use different `volumeThreshold` for different algorithms

Margins are already on the list.

algorithmSpecificSettings: {
[ControllerKind.CLONING]: {
marginBefore: 0.050,
marginAfter: 0.030,
},
[ControllerKind.STRETCHING]: {
...stretchingControllerSpecificDefaults,
},
},

Also maybe silenceSpeed also needs to be added there, although it's not used in the cloning algorithm yet.

The reason I think we need this is because with the cloning algorithm you don't really need to set volumeThreshold as low as possible because marginBefore actually works properly there without any stretching.

Suggestion: stats of time saved

I was hoping I could easily find/see time saved (eg minutes/seconds) when watching a video. Perhaps I'm not reading the UI properly?

It would be even cooler if it had long-term stats, like total time saved since installation of the addon (ublock has this).

Thanks, really loving this addon!

Does not work with local files

It gets initialized, but the audio does not get output.
The developer console says.

MediaElementAudioSource outputs zeroes due to CORS access restrictions for file:///<video file path>

A workaround would be to serve files from a local HTTP server (e.g. with python -m SimpleHTTPServer).

chore: automatize publish process

I remember the Video Speed Controller extension had this.
For Mozilla Add-ons store see web-ext, maybe it can help.
I don't think it should be fully automated though, better to keep it local, I think.

Since we now have localization, publishing more often is more desirable.

fix: use separate `AudioContext`s for each media element?

Using a shared one causes problems. See

// This is mainly to reduce CPU consumption while the video is paused. Also gets rid of slight misbehaviors like
// speed always becoming silenceSpeed when media element gets paused, which causes a guaranteed audio stretch on
// resume.
// TODO This causes a bug - start playing two media elements (on the same <iframe>), then pause one - both will get
// silenced. Nobody really does that, but still.
const suspendAudioContext = () => audioContext.suspend();

Maybe there are other problems related to this.
It should also prepare us for potentially attaching to several elements on the same document simultaneously.

IIRC the only benefit of using a shared one is performance. Not sure how bad creating several AudioContexts is, but I'm sure not super bad. But currently we only use one Controller at a time anyway, so it's not that we're gonna have a bunch of AudioContexts at simultaneously.
It used to be the case before fa678bf.

So I think we need to create a new one on each controller initialization.

Feature Request: Add option to always directly open unsupported media

First off, thanks for the awesome extension! Works like a charm!

I mostly use it to watch Lecture recordings, which are hosted on google drive (currently unsupported). For jumpcutter to work, I need to use the "open link directly" option - Do you think you could add a setting to make this a default option? Something like - always open links directly if possible.

Happy to help add this feature as well!

Thanks!
Vimal

Make the "experimental algorithm" (cloning) work on YouTube

Here's the idea: #2 (comment)

Roughly where to start looking:

private originalElement: HTMLMediaElement,
private settings: LookaheadSettings,
// public onNewSilenceRange: (start: Time, end: Time) => void,
) {
const clone = document.createElement('audio');
this.clone = clone;
// TODO this probably doesn't cover all cases. Maybe it's better to just `originalElement.cloneNode(true)`?
// TODO also need to watch for changes of `crossOrigin` (in `CloningController.ts`).
clone.crossOrigin = originalElement.crossOrigin;
clone.src = originalElement.currentSrc;

Website blacklist / whitelist

I found this extension on the Chrome Webstore -- I've absolutely fallen in love with how customisable it is, as well as the superb and powerful functionality.

Would it be possible to add a domain blacklist to control whether the extension should be disabled on certain pages? This would be very useful for e.g. speeding up lectures but keeping YouTube videos at normal speed.

I use this extension in combination with Video Speed Controller (with some overlapping features disabled), and they have what is shown in the following screenshot:

Screenshot 2021-09-21 at 20 41 04

Something like uBlock/AdBlock's "Trusted Sites" would also be similar (disable with a checkbox in extension popup, as well as multiline textbox in options).

Thanks!

Hide the badge (and darken the icon?) if there is no video

I've just installed and tested this extension. It works great!
The only thing I don't like about it is that green badge which is very green.

image

Maybe changing the color scheme to match the one seen on the uBlock Origin icon?
Or maybe also hide the badge entirely if there is no video element on the page?

Maybe even both things?

switch (settingName) {
// TODO DRY colors? Though here they're darker anyway, to account for the white text.
// TODO Also DRY `toFixed` precision, to match the popup?
case 'soundedSpeed': return [value.toFixed(2), '#0d0'];
case 'silenceSpeedRaw': return [value.toFixed(2), '#d00'];
// I guess it's better when it's blue and not red, so it's not confused with `silenceSpeed`.
case 'volumeThreshold': return [value.toFixed(4), '#00d'];
// TODO any better ideas for background colors for these two?
case 'marginBefore': return [value.toFixed(3), '#333'];
case 'marginAfter': return [value.toFixed(3), '#333'];
// default: assertNever(settingName); Does not work because of the generic type. TODO
default: throw new Error();

I see that there's a TODO there. What does DRY mean in that context?

A chat not requiring creating an account

We have a link to Discord, and we have GitHub, but they require an account. Would be cool if people could share their feedback more easily.

I heard of IRC.
And Matrix. Does Matrix require creating an account?
Zulip (lol)?

feat(popup): Always show the "open directly" link

To the right of "open a local file" would be a good place. Maybe also make it optional, as well as "open a local file"

Can be helpful if we didn't properly recognize if the media source is cross-origin.

Related to #36

Better pitch-shifting (time-stretching) algorithm

It's what causes the distortion on marginBefore parts:

"message": "When it's currently silent and then we encounter a loud part, how many seconds prior to it we need to slow down (switch to sounded speed).\nThis is mostly to ensure that you can clearly hear the very first letters when someone begins to speak.\n\n⚠️ Note that non-zero values will cause audio DISTORTION when switching from silence to sounded speed AND will add constant audio DELAY equivalent to the value of this setting. These drawbacks do not apply if you use the \"experimental algorithm\"."

It's used in the StretchingController.
Our current one is a very simple one, it's not very good for speech if at all:

this.speedUpPitchShift = new PitchShift();
this.slowDownPitchShift = new PitchShift();

https://github.com/Tonejs/Tone.js/blob/389685c7ff6c2ced43105bf4f9b42d8c4b75158b/Tone/effect/PitchShift.ts#L22-L23

This is a blocker for #14

Use `tabs.executeScript()` instead of `import()`

Maybe.
Using dynamic imports makes us have to add web_accessible_resources:

"web_accessible_resources": [
"content/SilenceDetectorProcessor.js",
"content/VolumeFilterProcessor.js",
"chunks/*.js"
],
, which is not ideal, as I heard: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources#security
It's also a little dangerous to not have the import URL set in stone, maybe it could be somehow manipulated by a malicious page to import something else on behalf of the extension (Mozilla's web-ext warns about this).
`const urlAbsolute = (typeof browser === 'undefined' ? chrome : browser).runtime.getURL(url)`,

Edit: Actually this doesn't look super dangerous, since we're passing the string through runtime.getURL(,

But then, it sounds a little stupid that there's virtually no native support for dynamic importing in extensions. Or am I missing something?

Another big thing is with .audioWorklet.addModule:

const addWorkletProcessor = (url: string) => audioContext.audioWorklet.addModule(browser.runtime.getURL(url));
For it we can't do executeScript(). Maybe the spec needs to be changed. I don't know what's the best practice.

This may also help with #26

Add automated tests

At least some basic, smoke-test level stuff. This should make things a little easier for new contributors.

Unit tests would be easier to implements, but I think end-to-end / Selenium are more valuable. Both are good, of course. Not sure if Selenium can work with extensions.

Mute silence parts (to avoid clicking sound)

Hi. Would it be possible to allow a setting to mute the silence parts? I hear a clicking/buzzing sound when those are sped up.

There's another extension that implements this (https://github.com/vantezzen/skip-silence) but I prefer yours because it has more granular settings and allows to play local files. However, this other extension has both the advantage of muting the silence and doesn't cause as much desynchronization for me

Thank you!

How to clone a YouTube video element so it can play the same video?

As a solution to #1, we could create another video element that plays the same video, hide it, and shift its playback for just a moment before the original video's .currentTime. That way we can effectively read the audio data that is yet to be played by the "main" video.

The problem is – I don't know how to clone a YouTube video element so it can play the same track.

This wouldn't work:

v = document.querySelector('video');
v2 = v.cloneNode(true);

Because

GET blob:https://www.youtube.com/79c3944d-0c45-412a-b5b2-c3d166d5c962 net::ERR_FILE_NOT_FOUND

So, how do I do it?

Summary of the below comments

fix: detect `<video>` inside custom elements (web components) (shadow DOM)

See

Affects: msn.com.

Where to fix:

for (const tagName of tagNames) {
const allMediaElementsWThisTag = document.getElementsByTagName(tagName);
if (allMediaElementsWThisTag.length) {
ensureInitAllMediaElementsController().then(allMediaElementsController => {
allMediaElementsController.onNewMediaElements(...allMediaElementsWThisTag);
});
}
}
// Peeked at https://github.com/igrigorik/videospeed/blob/a25373f1d831fe06430c2e9e87dc1bd1aabd25b1/inject.js#L631
function handleMutations(mutations: MutationRecord[]) {
const newElements: HTMLMediaElement[] = [];
for (const m of mutations) {
if (m.type !== 'childList') {
continue;
}
for (const node of m.addedNodes) {
if (node.nodeType !== Node.ELEMENT_NODE) {
continue;
}
// Keep in mind that the same element may get removed then added to the tree again. This is handled
// inside `handleNewElements` (`this.handledElements.has(el)`).
// Also the fact that we have an array of `addedNodes` in an array of mutations may mean (idk actually)
// that we can have duplicate nodes in the array, which currently is fine thanks to
// `this.handledElements.has(el)`.
if ((tagNames as string[]).includes(node.nodeName)) {
newElements.push(node as HTMLMediaElement);
} else {
// TODO here https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
// it says "The returned list is live, which means it updates itself with the DOM tree automatically".
// Does it mean that it would be better to somehow use the `allMediaElements` variable from a few lines above?
// But here https://dom.spec.whatwg.org/#introduction-to-dom-ranges it says that upgdating live ranges can be
// costly.
for (const tagName of tagNames) {
const childMediaElements = (node as HTMLElement).getElementsByTagName(tagName);

feat: non-infinite silenceSpeed for "experimental" (cloning) algorithm

Right now we're mostly performing seeks for this algorithm:

But also sometimes we speed up, this can be taken as a basis:

if (farEnoughToSpeedUp) {
// TODO what if `realTimeLeftUntilDestinationAtSilenceSpeed` is pretty big? Need to cancel this if
// the user seeks to a sounded place.
// May be other caveats.
this._setSpeedAndLog(SpeedName.SILENCE);

My idea: we can make it work roughly the same way as seeking works right now. It's inefficient, but should work:
On every 'timeupdate' event, check if we're on a silent or on a sounded part, set speed accordingly, check when the current silence (loudness) period ends and setTimeout to switch speed at that time.

We also need to think how it's gonna be on the UI. Do we just set speed to infinite when the "silence speed" slider is at max value? Or do we make a separate checkbox?

Related #48

Feature request: Presets

Hey, I'm really impressed with how well this extension works.
It would be really useful if the user could create named presets for settings (threshold, speed, margin ...) and select them easily.

Imagine watching lectures of different lecturers. Each professor speaks at their own pace. By using presets, the user could simply switch to the settings that fit a certain lecturer.

Lecture Speedrun has something similar, but your jumpcutter is more handy as it is packed as an extension (so videos don't need to be downloaded).

Look ahead audio samples

Currently, browsers don't offer us API that lets us simply get decoded audio samples of a video before actually playing them.

But we would like it since it would allow us to:

  1. Close #3
  2. Possibly to make it possible to not play silent parts at all (play them at a ludicrous speed).

Looking for a way to achieve this.

Twitch.tv: Silence speed capped at 2x unless sounded speed >= 2x

For some reason when sounded speed is below 2x (e.g. 1x, 1.5x), video speed is being capped at 2x during 0dB audio even with a very high silence speed (e.g. 3x, 5x, 10x). Works fine when sounded speed is 2x or higher.

E.g. https://www.twitch.tv/videos/1124147193 at 3:57:30

(I'm using https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk to see the video speed, not the inaccurate one at bottom right of video player.)

Allow higher than 4x Firefox

In the latest Firefox Beta 97.0b9 the cutoff speed for video with audio can be set in about:config and has as a default been increased to 8x
I use that version but the plugin currently does not support silent speed >4 and there is no config option for it!

Cross-origin restriction circumvention?

We can't directly analyze audio from video elements whose source is cross-origin, although they can be played back just fine. And this applies to many websites (Zoom call recordings, Invidious, Google Drive videos, many others).

Currently what we're doing is suggest opening the source directly in a new tab:
image

But would be cool if it just worked somehow. Preferably without violating what's cross-origin restriction is made for -

leaking information to the script where the cross-origin media element is played - you could say that information about which parts are silent and which are not could be considered that? But e.g. accessing `el.duration` can be considered this too? So maybe the cross-origin restriction in itself doesn't make too much sense in the first place? Or maybe it must also restrict the loading and playback of the media at all?)

Somewhat of an option is to contact the website owners and ask them to apply the required cross-origin headers to the source (I think it's Access-Control-Allow-Origin?) but you can't contact them all.

More info:

Advice or thoughts are appreciated (as always).

chore: upgrade Svelte and make sure build works

For some reason it started failing for Svelte >=3.48.

ERROR in .../tsconfig.json
.../tsconfig.json
[tsl] ERROR
      TS2688: Cannot find type definition file for 'shared'.
  The file is in the program because:
    Entry point for implicit type library 'shared'

FYI we don't exactly follow the guide https://svelte.dev/blog/svelte-and-typescript, specifically we don't have "extends": "@tsconfig/svelte/tsconfig.json", in tsconfig.json

Better Voice Activity Detection (VAD) (volume threshold) algorithm?

Currently we're simply calculating the loudness of incoming audio and if it's below a certain value, we say it's silence. Would be cool to find a specialized algorithm that does this better, like what voice communication apps do.
FYI in theory we can use an implementation written in a different language, such as C, C++, Rust, Go - we could compile it to WASM.

And it's not necessary to replace the current implementation, we can make an option to switch between different silence detection algorithms.

➕ Advantages:

  • Ignore noise, background music, only consider actual speech.
  • Make the "volume threshold" input less (or completely) unnecessary - make the extension simpler to use - not only if you're a beginner, but also because the best "volume threshold" value is different for different videos.
  • "Margin before" / "margin after" values also become the concern of the voice activity detection algorithm, not ours or user's.
  • May give an ability to add noise cancelation for output audio.

➖ Disadvantages:

  • Will probably need to do something about the chart, because it kind of makes drawing the volume threshold unnecessary (or even impossible)?
  • Need to make sure it's not too resource-demanding
  • It may have a bigger delay (i.e. more time to switch from silence speed to sounded speed). Although it's not that big of a concern when using the cloning algorithm.

Where to start:

Also see #164, there is a good collection of various VAD algorithms

I would appreciate your advice (as always).

I also found this: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/noiseSuppression
Idk what it is, but may help.
Also this: w3c/webrtc-extensions#76

What to work on

Superb UI, but some sort of processing error

Edit: Working okay so far today. Apparently you can't easily delete issues so I'll leave this for a day or two and close if I can't repro again today.

Edit 2: I was running into #25 repeatedly last night and maybe it was confusing everything.

This is a vague not-particularly-useful issue report, but on Chrome I've been comparing Jump Cutter to Skip Silence, and I much prefer the UI of Jump Cutter. It's the one I want to work.

However, even after adjusting every setting, e.g. setting a 0.5s "margin before" (the distortion & delay don't bother me much), and a decent "margin after" of 0.25s, there is some sort of audio error that still occurs repeatedly. Essentially every 1-3 minutes I won't be able to make sense of what I just heard due to choppiness in their voice. I will jump back and re-play it, and it will play perfectly the second time.

Perhaps it is switching too fast? Too many times in a short period? Seems to happen no matter my margin settings, large or 0.
I thought I was stuck with this until I tried Skip Silence, and it doesn't have this issue, seems to playback perfectly. Perhaps because of its "Sample Threshold" setting? It seems like "margin" is perhaps the equivalent of that in Jump Cutter, but as mentioned something doesn't quite work.

Anyway, love the extension, I much prefer your volume graph and threshold setting - the way the graph scales, it's awesome. But currently have to use Skip Silence instead because of this issue. (After testing each on a few hours of video last night.)

Will see if I can gather more useful information, switching back to Jump Cutter to try to find some helpful repro's.

🌐 Help translate!

https://hosted.weblate.org/engage/jump-cutter/

Also see https://github.com/WofWca/jumpcutter/tree/translations#readme

Don't hesitate to ask questions.

If you've made a translation but the extension doesn't appear to display in that language, please reach out to me. I might have messed up language codes.

Side note: If you want translation activity to be displayed on your GitHub profile, you also have to star or fork WofWca/jumpcutter-translations. It's because translations are used as a submodule in the current (main) repo. See GitHub docs.

Suggestion: increase visibility of settings icon? ⚙️

I accidentally saw the gear icon for the first time today - actually, that's not true. I actually found the options from "Extension options" from my chrome://extensions/?id=lmppdpldfpfdlipofacekcfleacbbncp page first. I was shocked when I saw all the extra configurations!

I then opened Jump Cutter specifically looking for a direct link to the options and spotted the gear at the top right. I've opened Jump Cutter a lot and never saw that, I think because an ultrawide (3440x) resolution makes the "teeth" of the gear almost invisible, just a pixel or two: image.

I'm actually a lot more impressed with Jump Cutter than before even! Though I still can't use it on Twitch except for very slow speakers because of #25 😁, it's pretty great!

Feel free to close this suggestion as won't fix btw, not every suggestion is a good one 😅.

Fix the "Z" default hotkey

// In case you coulnd't make it out. Practically turns on/off the extension. Why not actually turn it on/off?
// Because
// * We don't have such a hotkey action yet.
// * Hotkeys would also cease to work if we'd disable it.
// * It would create an audio glitch (at best), at worst it would remove/add audio delay (becaouse of how
// marginBefore) works.
// * It's computationally heavy.
// TODO these problems sound like then can be solved.
{
keyCombination: { code: 'KeyZ', },
action: HotkeyAction.TOGGLE_VOLUME_THRESHOLD,
actionArgument: 0,
},
{
keyCombination: { code: 'KeyZ', },
action: HotkeyAction.SET_SOUNDED_SPEED,
actionArgument: 1,
},

It's supposed to be like a quick extension toggle (without de(re)initialization). I personally set it to toggle both sounded speed and volume threshold, but the problem is if you decide to "switch off" the extension while the sounded speed is 1 alredy, it will toggle it to the previous value.

Best solution I can think of is to create a separate HotkeyAction for this instead of binding two actions (HotkeyAction.SET_SOUNDED_SPEED and HotkeyAction.TOGGLE_VOLUME_THRESHOLD) to the key.

Adjust badge colors

Chromium now apparently uses black color for the text, so may need to brighten up the colors. Maybe choose the same as on the chart.

image

feat: an option to not use the global "sounded speed" setting at all

After 1c82c22 I thought that for some people it would be better if we did not attempt to change the default playback rate of media elements at all. For example, on one website they watch videos at 2.5x speed, on another it's 1.5x, but they want silence skipping to work on both of them. But currently our extension always sets sounded speed to the value stored in its settings, so if they visited the first website (where they watch at 2.5x), and then went to the second one (where they prefer to watch at 1.5x) – tough luck – our extension will set it to 2.5x.

I guess we could make the "sounded speed" setting not global but per-element. Also, maybe this should apply to "silence speed" as well? And other settings?

Also, how about instead of having such setting stored somewhere in the extension's code, we simply use el.defaultPlaybackRate is the value for it?

For this we can look up how the Video Speed Controller extension works.

feat: update "Sounded Speed" setting when playback rate gets changed through the website

For example on YouTube (without this extension) there is a way to change playback rate. But if a user does this, the new playback rate will be overridden by the value of "sounded speed". So we need to update it.
I'd say it's of big confusion and annoyance to new users.
Also it's a step towards compatibility with other playback rate changing extensions (like "Video Speed Controller").

I guess we need to element.addEventListener('ratechange' and inside the the listener we need to check whether this playback rate change was caused by the extension or by something else. If it's something else, update "soundedSpeed".

Playback rate changes are performed inside controllers:

https://github.com/WofWca/jumpcutter/tree/dev/src/entry-points/content

e.g.

So I guess every time a controller does this, it should call a callback or something like this.

License?

There is no license here or on Weblate.
This seems to be in error(?)

refactor: separate some hotkey code into a library

Like this, for example:

/**
* If a key is pressed while typing in an input field, we don't consider this a hotkey.
* Filter criteria is yoinked from
* https://github.com/ccampbell/mousetrap/blob/2f9a476ba6158ba69763e4fcf914966cc72ef433/mousetrap.js#L1000
* and alike libraries. Another reason to rewrite all this using a library.
*
* TODO how about we also/instead check if the target element is a parent of the video element that we're controlling?
*/
export function eventTargetIsInput(event: KeyboardEvent): boolean {
const t = event.target as Document | HTMLElement;
return (
['INPUT', 'SELECT', 'TEXTAREA']
// @ts-expect-error 2339 for performance because doing `'tagName' in t` would be redundant, because
// it is present most of the time.
.includes(t.tagName)
// @ts-expect-error 2339 same as above
|| t.isContentEditable
);
}

As stated in the comment, the criteria is already taken from another library.

Create gh-pages (a website) where you can try out the extension without installing it

This is also helpful for people who are afraid (or other reasons) to install the extension (see #57).

Also need to consider making it an installable PWA, to play local (or non-local?) files.

Maybe also need to add a way to open non-local files in the local-file-player, with a link to the video file.

The biggest obstacle here is the usage of Web Extension API (e.g. browser.tabs.query(...).

Maybe we can add some ifs like (if (BUILD_DEFINITIONS.STANDALONE_DEMO_PAGE), so that Web Extension API is never used when the condition is true. So basically search for all the occurrences of browser..

I think we could utilize local-file-player and put popup in an <iframe>.

For popup, this may also help: https://github.com/WofWca/jumpcutter/compare/popup-separate-tab

Setting Sounded speed to 0 causes Jump Cutter to stop responding

When watching a video with Jump Cutter enabled, dragging the Sounded speed slider to 0.00 causes the video to stop playing and the extension popup to stop responding (dragging the sliders has no effect; values stay unchanged).

Repro steps

  1. Play a video with Jump Cutter enabled
  2. Open the Jump Cutter popup
  3. Drag the Sounded speed slider to the left (0.00)
  4. Wait a fraction of a second (to stop debouncing)
  5. Video playback stops
  6. Drag the Sounded speed slider (or any other slider) to any other value (or click the Enabled checkbox)

Actual result

Noting happens. All values stay the same. Video playback does not continue.

Expected result

Jump Cutter should not hang; video should start playing again after dragging the slider (and other sliders and checkboxes should continue working)

Version

Version: 1.18.1
Firefox 92.0

Screenshot

Notice how the value of Sounded speed is still 0.00, although the slider has been dragged to a different value.
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.