wavesurfer.js icon indicating copy to clipboard operation
wavesurfer.js copied to clipboard

regions plugin randomly doesn't loop

Open swampthang opened this issue 2 years ago • 5 comments

To start let me say I LOVE wavesurfer-js! Very grateful for what it has become.

Wavesurfer.js version(s):

6.2.0

Browser and operating system version(s):

Chrome: Version 103.0.5060.114 (Official Build) (x86_64) OS: Mac OS 11.6.1 (20G224) Big Sur

Code needed to reproduce the issue:

https://codepen.io/swampthang/pen/OJZNzMb?editors=1010

Use behavior needed to reproduce the issue:

I have several audio files I'm setting up to loop a region. Pretty much every file works but this one (so far) so there seems to be something peculiar about this file or maybe the loop end point is getting caught between frames. It WILL loop sometimes once and sometimes maybe even twice but often doesn't loop at all.

Any ideas about how I might be able to help debug this?

The loop end time in the codepen is 6.8571428571428 but I've tried rounding it up to 6.85714 and it behaves in the same way. I've also seen the same thing in Firefox and Safari.

swampthang avatar Sep 09 '22 17:09 swampthang

These loop points are meant to create a looped track to play along with so they need to be at specific points (musicial measures). As an update, I noticed that when I change the region end time to 8.587755 it works but 5.152653 doesn't.

swampthang avatar Sep 09 '22 18:09 swampthang

Pretty much every file works but this one (so far) so there seems to be something peculiar about this file

Use ffprobe (part of FFmpeg) to compare the differences between the files.

thijstriemstra avatar Sep 09 '22 23:09 thijstriemstra

Use ffprobe (part of FFmpeg) to compare the differences between the files.

Thanks for the reply. I'm finding that any file at that tempo attempting to loop at that same point results in the same issue. Here's the ffprobe diff... ONE THAT DOESN'T LOOP AS EXPECTED:

ffprobe -hide_banner -loglevel debug  a-1-b7-4-1.mp3
[NULL @ 0x7ff33ec06b00] Opening 'a-1-b7-4-1.mp3' for reading
[file @ 0x7ff33ec06ec0] Setting default whitelist 'file,crypto,data'
[mp3 @ 0x7ff33ec06b00] Format mp3 probed with size=4096 and score=51
id3v2 ver:4 flags:00 len:35
[mp3 @ 0x7ff33ec06b00] pad 576 0
[mp3 @ 0x7ff33ec06b00] Skipping 0 bytes of junk at 462.
[mp3 @ 0x7ff33ec06b00] Before avformat_find_stream_info() pos: 462 bytes read:32768 seeks:0 nb_streams:1
[mp3 @ 0x7ff33ec06b00] demuxer injecting skip 1105 / discard 0
[mp3float @ 0x7ff33ec07700] skip 1105 / discard 0 samples due to side data
[mp3float @ 0x7ff33ec07700] skip 1105/1152 samples
[mp3 @ 0x7ff33ec06b00] All info found
[mp3 @ 0x7ff33ec06b00] After avformat_find_stream_info() pos: 21966 bytes read:32768 seeks:0 frames:50
Input #0, mp3, from 'a-1-b7-4-1.mp3':
  Metadata:
    encoder         : Lavf55.12.100
  Duration: 00:00:15.83, start: 0.025057, bitrate: 128 kb/s
  Stream #0:0, 50, 1/14112000: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s

One that works fine...

ffprobe -hide_banner -loglevel debug  A.mp3
[NULL @ 0x7fb0e4e05bc0] Opening 'A.mp3' for reading
[file @ 0x7fb0e6215100] Setting default whitelist 'file,crypto,data'
[mp3 @ 0x7fb0e4e05bc0] Format mp3 probed with size=8192 and score=51
id3v2 ver:3 flags:00 len:73
[mp3 @ 0x7fb0e4e05bc0] pad 576 842
[mp3 @ 0x7fb0e4e05bc0] Skipping 0 bytes of junk at 1127.
[mp3 @ 0x7fb0e4e05bc0] Before avformat_find_stream_info() pos: 1127 bytes read:32768 seeks:0 nb_streams:1
[mp3 @ 0x7fb0e4e05bc0] demuxer injecting skip 1105 / discard 0
[mp3float @ 0x7fb0e6215880] skip 1105 / discard 0 samples due to side data
[mp3float @ 0x7fb0e6215880] skip 1105/1152 samples
[mp3 @ 0x7fb0e4e05bc0] All info found
[mp3 @ 0x7fb0e4e05bc0] After avformat_find_stream_info() pos: 54375 bytes read:65536 seeks:0 frames:50
Input #0, mp3, from 'A.mp3':
  Metadata:
    artist          : Carvel Avis
    encoder         : Studio One 5.5.1.85792
    date            : 2022
  Duration: 00:00:29.57, start: 0.025057, bitrate: 320 kb/s
  Stream #0:0, 50, 1/14112000: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      encoder         : LAME3.100
[AVIOContext @ 0x7fb0e6215280] Statistics: 65536 bytes read, 0 seeks

In musical terms, the ones that don't work are at tempo of 140 in 4/4 time and are supposed to loop after the 4th measure. I can edit one of the those same files by duplicating the first 4 measures and setting the loop to be after the 8th measure and all works fine.

swampthang avatar Sep 12 '22 16:09 swampthang

Try converting the bad file to .wav, maybe ffmpeg can strip out the garbage..

thijstriemstra avatar Sep 12 '22 16:09 thijstriemstra

Try converting the bad file to .wav, maybe ffmpeg can strip out the garbage..

I had tried that but it still seems to be related to the time. I wonder if there's some kind of weird computer math issue. As I'm sure you know, .1+.2 = 0.30000000000000004 in the browser (not .3)

The "good" file jumps the loop after the first time if the loop is set to jump between 0 and 6.8571428571428 (the first 4 measures at that tempo.) But, it works great if the loop is set to between 0 and 13.7142857142856 using the same file.

swampthang avatar Sep 12 '22 18:09 swampthang

I've been experiencing the same issue where looping is inconsistent for some files, for some regions. I'm also using an mp3 source and using the MediaElement backend. It seems it may be somewhat file-specific in that certain audio files seem to exhibit this problem more often than others do.

For a workaround, at least in my case the "region-out" event is still fired when the region doesn't successfully loop, so you can manually call the region play() method in that callback, e.g.

ws.on("region-out", (region) => {
	region.playLoop();
});

This doesn't perfectly replicate the loop feature, e.g. you can't scrub out of the region (and also presumably you'd want to add in some logic to allow the looping to eventually stop), but it does at least get the region to loop consistently.

alexaschor avatar Oct 29 '22 23:10 alexaschor