There has been an extensive refactor of wavesurfer within the last half year which resulted in a version which includes a lot of new features (namely a dynamic plugin system) but also some breaking changes. We have decided to release it as a version two. Changes to either branch will be ported to each other (especially bug fixes of course).
This issue is intended as a place for general discussion and feedback regarding the v2 release.
Edit 1: Added change I forgot to mention: MultiCanvas is the default and only inbuilt renderer
The version is _mostly_ stable and functional. Due to the nature of the refactor (an integrated plugin system for adding, initialising and destroying of plugin instances) all plugins are somehow affected. Some plugins are still buggy when used with the dynamic plugin API. Conventional use cases (i.e. cases where you just want to create an instance with some plugins โ no dynamic adding or removing โ should work just fine) (Below in the plugin API examples, this means 1. should already work, 2. and 3. don't yet always work in all situations and for all plugins)
To get the current beta release (at the time of writing) do npm install [email protected]
You can find the beta release(s) on the releases page or by running npm show wavesurfer.js | grep beta
To work on the new branch checkout the next branch, do npm install and then npm start โ The library directory is exposed under http://localhost:8080
Generate the documention by running npm run doc (see below) โ Tests can be run by calling npm run test
There are still lots of things which need doing. We welcome and are thankful for any help we can get. Please see right at the bottom of this post how you can help us.
(See a full list of all merged PRs for v2)
// EITHER - accessing modules with <script> tags
var WaveSurfer = window.WaveSurfer;
var TimelinePlugin = window.WaveSurfer.timeline;
var MinimapPlugin = window.WaveSurfer.minimap;
// OR - importing as es6 module
import WaveSurfer from 'wavesurfer.js';
import TimelinePlugin from 'wavesurfer.js/dist/plugin/wavesurfer.timeline.min.js';
import MinimapPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.minimap.min.js';
// OR - importing as require.js/commonjs modules
var WaveSurfer = require('wavesurfer.js');
var TimelinePlugin = require('wavesurfer.js/dist/plugin/wavesurfer.timeline.min.js');
var MinimapPlugin = require('wavesurfer.js/dist/plugin/wavesurfer.minimap.min.js');
./doc by calling npm run doc) โ The idea being that it is easier to keep documentation up to date easier than having to always edit HTML code in the gh-pages branch.window.WaveSurfer global variable. This made it difficult to work with module bundlers (You had to expose the WaveSurfer object, which means it's not really modular) โ To fix this plugins now all follow a common format which is used by wavesurfer core to register the plugins correctly. (see an example of a plugin class at the bottom of this post)There are three ways to add a plugin:
var wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: 'violet',
plugins: [
TimelinePlugin.create({
container: '#wave-timeline'
})
]
});
var wavesurfer = WaveSurfer.create({
container: '#waveform',
plugins: [
TimelinePlugin.create({
container: '#wave-timeline',
deferInit: true // stop the plugin from initialising immediately
})
]
});
wavesurfer.initPlugin('timeline');
var wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: 'violet'
});
// adding and initialising a plugin after initialisation
wavesurfer.addPlugin(TimelinePlugin.create({
container: '#wave-timeline',
})).initPlugin('timeline');
Also a plugin can be destroyed like this:
wavesurfer.destroyPlugin('timeline');
html-init.js was extended to allow more complicated initialisation options (including autoloading of plugin code) โ see #946 โ Example usage:<wavesurfer
data-url="../media/demo.wav"
data-plugins="minimap,timeline"
data-minimap-height="30"
data-minimap-wave-color="#ddd"
data-minimap-progress-color="#999"
data-timeline-font-size="13px"
data-timeline-container="#timeline"
>
</wavesurfer>
<div id="timeline"></div>
All plugins now follow a common format and their initialisation is handled by wavesurfer core. It is no longer necessary to manually initialise them.
export default class MyAwesomePlugin {
/**
* MyAwesome plugin definition factory
*
* This function must be used to create a plugin definition which can be
* used by wavesurfer to correctly instantiate the plugin.
*
* @param {MyAwesomePluginParams} params parameters use to initialise the
* plugin
* @return {PluginDefinition} an object representing the plugin
*/
static create(params) {
return {
name: 'myawesome',
deferInit: params && params.deferInit ? params.deferInit : false,
params: params,
staticProps: {
staticMethod() {
// this will be added to the wavesurfer instance and can then be called
// wavesurfer.staticMethod();
}
},
instance: MyAwesomePlugin
};
}
constructor(params, ws) {
// instantiate the plugin
}
init() {
// start doing something
}
destroy() {
// stop doing something
}
}

@mspae I've force-pushed next into the master branch, so that we can accept PRs into the next branch by default. Should've done it long ago.
How do we go about backporting the PRs that got merged into the old master?
_Edit_: apparently, this diff can serve as a rough overview of things that need to be merged into the next branch.
Hey, sorry for the long absence. Unfortunately I'm pretty busy with work right now, so I don't have that much time to commit to working on wavesurfer core fully at this time.
I think concerning the unported changes (= stuff from es5 which isn't in es6 yet) there is nothing for it but to grind them down until we are up to date. But maybe we need to organise this in a clever way to maximise the effect of our time.
I just looked through the diff you mentioned and I think the commits can be categorised like this:
Then there is of course the question of open PRs โ I think bug reports specific to the es6 branch have not been flooding in, so I'm assuming that either people are not using it that much or that it is largely stable.
I have the feeling that there is still quite a bit of friction involved in maintaining this library โ which kind of makes it difficult to do small bits of work on it because it is necessary to think of lots of things at the same time. Maybe it would be a good idea to automate more of the process:
First PR for the first part is out โ I checked approximately half of the commits that were different, here is the list
This list includes all commits that are different that are later than "Commits on Mar 12, 2017"
Second PR is out (#1193). I checked the other half. The only unmerged ones (the red circles) are plugin changes. I also didn't merge all the changelog changes so I can simply copy the current changelog in one go.
Updated one of my plugins and wasn't too much work: https://github.com/collab-project/videojs-wavesurfer/compare/wavesurfer2
When can we expect a next release?
How about this weekend? Version 2.0.0 without the beta, right?
A beta 2 would not hurt (or RC1).
@mspae can you roll a new release (beta2) for the current master? I have some things I want to test.
@thijstriemstra I can only tag, I cannot publish to NPM. AFAIK only @katspaugh can do that.
Ping @katspaugh
Tagged & published!
Awesome thanks!
Well it (still) works fine, so I'm +1 on a final release this week!
@mspae @katspaugh can we set a release date for 2.0.0? 1st of october? tomorrow? I'll help out where I can.
So I'm in two minds about this: On the one hand staying in beta makes it clear that there may be bugs we don't know about, on the other hand this is really also the case for a proper release. Stability is subjective and relative :smile_cat:
Also there is the matter of semver: releasing 2.0.0 means we can't break backward compatibility until we release 3.0.0 so we need to be really sure that this won't happen before we make the final step and go out of beta.
In light of this I would propose we do this:
As a timeplan proposal: I think we should do the first step (see above) ASAP then aim to release 2.0.0 by the 10th of october.
I'm also working on a major overhaul of the website (more docs, more consistent design, bootstrap v4 etc) โ it will also fix #1090 โ I'm about 60% of the way and want to have this finished by the 2.0.0 release.
So that would be my proposal. This is of course open to discussion. I would be really happy for help with any of the above.
UPDATE: Updated the prettify point with the PR for that.
Also, freezing API till v3.0 and all regtession testing seems way too strict. Its useful but it changes the dynamic of this project where before it was loosely maintained and released as often as possible. Having all this testing also requires reviewers and we don't have that manpower or userbase to help out from my experience with this project for last couple of years.
I totally agree with the "we need more releases" position.
I'm not proposing we stop adding features until 3.0.0, but to follow semantical versioning we can't break backward compatibility between releases in a major version. And for this purpose I think it is essential to have testing in place to make sure new features don't break existing functionality.
I don't quite see testing conflicting with loose maintenance. In my view it is absolutely necessary to be able to quickly add features and merge PRs, the alternative would be to either manually test any new code (which IMHO conflicts with the "loosely maintained" concept) or to simply hope nothing breaks (which means there can never be any reasonable amount of confidence in the stability of releases)
So yes, adding and maintaining tests is overhead which doesn't add features. I see that. But on the other hand it allows us to delegate a lot of the tedious part of the reviewing process (testing functional stability) to the CI system. This frees contributor resources which can be used for architectural discussion, documentation, support and new features. So I think testing actually saves a lot of time in the long run.
I understand your argument regarding the breaking changes in #1210 โ It does delay the potential 2.0.0 release date because we need to make sure breakage does not occur. But for the reasons stated above I think it's worth it. In addition to the testing itself and the changes of the events the PR also contains a lot of fixes for bugs which were never reported because they only appear in certain param combinations and interactions. Having this kind of testing prevents these bugs from cropping up unnoticed in future.
What I can offer as a compromise:
This way we can release immediately. What do you think?
@mspae What's the status now? I think we should really release this asap (before end of year) because I feel it's damaging the project that there hasn't been a new release in such a long time. @katspaugh thoughts?
@thijstriemstra That's what I meant in https://github.com/katspaugh/wavesurfer.js/issues/1092#issuecomment-333311162 โ we can release now as far as I'm concerned. But I don't have publishing rights, so it's not up to me.
@katspaugh seems to be missing in action :fearful:
@thijstriemstra sorry, missed your previous message.
Publishing!
Edit: I've removed the beta postfix and published the package (see https://github.com/katspaugh/wavesurfer.js/commit/4a93027e15ab2cf35e017515f6cb7c0f3c84aa55).
Congratulations and thanks a lot!
Thanks! 2.0.0 is now available on https://www.npmjs.com/package/wavesurfer.js, on to next release!
@katspaugh unfortunately it seems something went wrong with the release, the dist folder is missing from the npm package:
$ ls node_modules/wavesurfer.js/
CHANGES.md LICENSE package.json README.md src
People starting to notice: https://github.com/katspaugh/wavesurfer.js/issues/1273
I opened #1274 that will build the dist folder when you run npm publish, can you take a look @katspaugh and release a new 2.0.1?
Most helpful comment
A beta 2 would not hurt (or RC1).