bbc / peaks.js

JavaScript UI component for interacting with audio waveforms
https://waveform.prototyping.bbc.co.uk
GNU Lesser General Public License v3.0
3.16k stars 275 forks source link

Prevent auto-scrolling of the waveform on click #497

Open chrisn opened 1 year ago

chrisn commented 1 year ago

So, is there any way to stop the auto-scrolling of the waveform when you click on the last second of the currently rendered view?

For my project, I wanted to add the functionality of creating a new segment by double-clicking on zoomview. Now, if I double-click around the end of the waveform (let's suppose 12 seconds are rendering in the current view and I double-click between the 11th and 12th seconds), the waveform is scrolling automatically, and I am not able to create the segment on the selected time stamp. It is getting created on another timestamp (12 plus the timestamp I clicked on).

I have attached a video to show my issue. As you can see, in the first rendered view, we can see approximately the first 12 seconds. When I double-clicked to create the segment, it jumped onto the next view, and my segment was created approximately at the 23rd second.

https://github.com/bbc/peaks.js/assets/107407402/a116689b-577b-4a84-9905-d15e4083f00d

Originally posted by @NinjaCoderDotCom in https://github.com/bbc/peaks.js/issues/495#issuecomment-1592481054

chrisn commented 1 year ago

By default, clicking the waveform changes the playback position (seek). When the playback position reaches the edge of the view, it updates the visible range.

This will prevent the seeking, and hence the view won't change:

const view = peaksInstance.views.getView('zoomview');
view.enableSeek(false);

This will allow the seek but prevent the view from updating:

const view = peaksInstance.views.getView('zoomview');
view.enableAutoScroll(false);
vivekd95 commented 1 year ago
peaksInstance.on('zoomview.click', function (event) {
       const view = peaksInstance.views.getView('zoomview');
       view.enableSeek(false);
})

Are you suggesting that I should do this? If yes, then that will restrict my seeking when I am not clicking near the right edge of the waveform.

chrisn commented 1 year ago

How would you like it to work? Possibly something like this?

peaksInstance.on('zoomview.click', function(event) {
  event.preventSeek();
});
vivekd95 commented 1 year ago

So, will it just restrict the seeking when I click at the right edge of the waveform?

I was just thinking of kind of a patch on my side only. Something like this:

var zoomview = peaks.views.getView('zoomview');
zoomview.enableSeek(false); // Keeping seeking to false and auto-scrolling to true.

peaksInstance.on('zoomview.click', function(event) {
     if(event.time < viewEndTime - 1.1)) {
          peaks.player.seek(event.time);
        }
});

Do you think this is a good way? Actually, I have multiple cases to run on my zoomview that's why I have to check if zoomview.click is triggered when I am clicking way far the right edge of the waveform or near it. If adding preventSeek() from your side resolves the issue of applying this patch thing that I did, then it will be helpful.

chrisn commented 1 year ago

This is more complicated than I thought. Seeking doesn't happen inside Peaks click handler, instead it uses mouseup. That means simply adding a preventSeek() isn't going to work.

I tried the code you suggested and the only issue I found is that it sometimes does a seek after dragging to scroll the waveform, which Peaks doesn't do by default. But that may be OK for you?

vivekd95 commented 1 year ago

Yes. For now, this patch is working for me. But after performing deep debugging, I found out that although scrolling of the waveform on the click near the right edge of the waveform is happening the segment is being created at the correct time. The same is happening in my project but something the waveform jumps. Hence, it might be a problem with my code.

Thanks for the help and support you provided.

vivekd95 commented 1 year ago

Also, here are some advice and suggestions regarding waveform scrolling. Right now, if you have enableAutoScroll set to true, the waveform is scrolling automatically when the seeker enters the last second of the rendered view (approximately).

Ideally, waveforms scroll when the seeker reaches the end of the waveform, i.e., at the exact last timestamp of the rendered view when playing. Although you can provide an option or way for the user to set when it should scroll, the default value is the same as it is now. For example, the user can get the end time of the currently rendered view and set it as the auto scroll point when the video is playing (or something like that).

I would also like to add that waveform does not scroll when clicked manually, even at the last second. Scrolling happens only in the case of media playing or manual scrolling via mouse or touchpad.

chrisn commented 1 year ago

Ideally, waveforms scroll when the seeker reaches the end of the waveform, i.e., at the exact last timestamp of the rendered view when playing. Although you can provide an option or way for the user to set when it should scroll, the default value is the same as it is now.

Adding options to control this is a good suggestion, thank you. The current behaviour clicking within 100 pixels of the right edge of the view will scroll forwards.

I would also like to add that waveform does not scroll when clicked manually, even at the last second. Scrolling happens only in the case of media playing or manual scrolling via mouse or touchpad.

Having it only scroll during media playback should probably be the default behaviour. If playback is stopped and you click to seek, I wouldn't expect the view to scroll.