wavesurfer.js
wavesurfer.js copied to clipboard
Regions plugin variant - chapters / non-overlapping regions? + bug in zoom with regions
The regions plugin is pretty close to what I really need, which is the ability to visually split audio in multiple non-overlapping chapters (with microsecond accuracy, using the zoom level). Regions plugin is nearly what I want, apart from the overlap (which you have previously talked about).
It seems that I have to override onResize
to each region, then use the offset supplied by that event to update the adjacent region start/end. But waversurfer.regions.list
isn't arraylike so it's not easy to grab adjacent regions.
Here's a pen demonstrating: https://codepen.io/frumbert/pen/MOGrKm
I'd also like to use Zoom for more accurate edge selection, but I've noticed you can zoom out which scales the regions down but doesn't scale the waveform itself (also seen on this pen). I haven't yet been able to figure out how to calculate the default zoom of 100% (pixels per second isn't the easiest system to work with). I added the timeline plugin to the zoom and you can see the regions scale whilst the timeline and waveform do not, once you go too low.
There's difficulty working with the edges of a region when it is touching another region - puling the adjacent marker will always prioritise the right-most region. Say you had two regions
wavesurfer.addRegion({ start: 0, end: 5 })
wavesurfer.addRegion({ start: 5, end: 10 })
then you try to resize the first's end marker, you'll end up pulling the seconds start marker. I'm sure this has to do with how layering works in the html dom (z-index, and so on).
In my code there's also a bug when resizing the regions on the right side of the waveform (but not the left). Sometimes pulling the right edge of a region will also change the left edge's position. Since the resize isn't an event, I can't hook it and adjust adjacent regions accordingly (which would be ok but not ideal: why can pulling one side affect the other?). Once you fiddle with the zoom this problem becomes more prevalent.
Lastly, regions are still able to overlap. This is primarily the functionality that I need over-ridden: regions musn't overlap. I need to be able to block a resize inside the onMove of its handler so that it can't be moved passed a certain point. If the resize and drag emitted events that I could block, that would be awesome.
I would like to have non-overlapping regions too in my project, so i am planning to improve Regions plugin with this kind of features (for wavesurfer v2 only).
@frumbert However, I would like to discuss the behaviour of such a feature, did you think it through, and are you still interested in this improvement ?
Here is a first brainstorm question i have:
- When moving a region, does it reduces the neighbours boundaries, or is "blocked" by it (so dragging is limited by previous and next regions).
- When resizing regions / dragging those boundaries, same question, is it limited, or does it reduce other regions boundaries ?
- If dragging resizes neighbours, can a region "remove" a neighbour (if its size is reduced to zero).
- If not resizing but limited by... if 2 regions are completely adjacent, does dragging should be "sticking", i.e. dragging both boundaries at the same time ? Should it be a dedicated feature (like a flag 'stickyBounds' ?
@ArTiSTiX : I prototyped the generic part of region selection and boundary dragging the way I'd like this to work - not as a hack in wavesurver, just as regular splitter in the dom as a POC. Obviously there's no waveform shown here or zooming etc. It's pretty clunky. Here's a gif:
- light-blue dashes are the regions. white space between them are the draggable boundaries.
- Regions don't overlap
- You can't drag a boundary beyond the start or end of adjacent regions
- Regions are selectable, but you can't drag/move the region itself, you need to drag its boundary.
SO I see the entire waveform as a series of regions; they are sequential, non-overlapping, the end of one region is the same as the beginning of the next.
I create a basic region operation Demo for audio annotation based on built in Region plugin. But it only meets some of my needs now. May I ask @frumbert have you developed your prototype, I am excited about your plugin.
I followed this way to solve Overlapping. It is not very performing but it works.
I sorted the labels in the Initializer. Then I defined beforeLabel and nextLabel in the "attributes" field of each label. If there is a label before or after, I assigned it to variables. (You can see the sample code below.)
regionSorted.forEach((region, index) => {
if(regionSorted[index+1]) {
wavesurfer.regions.list[region.id].attributes.nextRegion = regionSorted[index+1]
}
if(regionSorted[index-1]) {
wavesurfer.regions.list[region.id].attributes.backRegion = regionSorted[index-1]
}
})
In the "region-updated" event, I made a definition like this.
wavesurfer.on('region-updated', region => {
//.......
if(region.attributes.nextRegion && region.end > region.attributes.nextRegion.start) {
region.end = region.attributes.nextRegion.start
}
if(region.attributes.backRegion && region.start < region.attributes.backRegion.end) {
region.start = region.attributes.backRegion.end
}
//.......
})
Is there any new way?
hey @bilalcorbacioglu can u plz explain how u make regionSorted array if u have code???
does anyone have solution to this? @bilalcorbacioglu @HassanAslam @ArTiSTiX