mspae / react-wavesurfer Goto Github PK
View Code? Open in Web Editor NEWReact component wrapper for wavesurfer.js
License: BSD 3-Clause "New" or "Revised" License
React component wrapper for wavesurfer.js
License: BSD 3-Clause "New" or "Revised" License
Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
https://facebook.github.io/react/docs/typechecking-with-proptypes.html
Should be an easy fix.
This line:
// set initial volume
if (this.props.volume) {
this.wavesurfer.setVolume(this.props.volume)
}
should be:
// set initial volume
if (this.props.volume != null) {
this.wavesurfer.setVolume(this.props.volume)
}
because 0 or 0.0 will evaluate to false.
Hello,
After the file has finished playing, and the cursor on the wave is moved back, the player still doesn't play the audio, even though the prop playing === true, and pos is now somewhere in the middle of the file.
Hi, everyone!
When I am trying to import react-wavesurfer, I am getting an error saying:
Error in ./~/react-wavesurfer/lib/react-wavesurfer.min.js
Module not found: 'wavesurfer.js' in /home/username/Projects/test/frontend/node_modules/react-wavesurfer/lib@ ./~/react-wavesurfer/lib/react-wavesurfer.min.js 1:99-123
Although, the wavesurfer package (https://www.npmjs.com/package/wavesurfer) is installed.
First I tried to add the following to webpack config:
{
test: require.resolve("wavesurfer.js"),
loader: "expose?WaveSurfer"
}
and
{
test: require.resolve("wavesurfer.js"),
loader: "expose-loader?WaveSurfer"
}
but I received the similar error saying that there is no module wavesurfer.js. And indeed there was no module called "wavesurfer.js", but there was "wavesurfer" module. So I went to node_modules/react-wavesurfer/lib/react-wavesurfer.min.js and changed require("wavesurfer.js")
to require("wavesurfer")
and everything started working. Should I use another wavesurfer npm package or is this a bug?
Thank you.
The documentation on original wavesurfer is a bit light, but it seems like to enable pre-rendered waveforms one would use a load like so
wavesurfer.load('../media/demo.wav', [
0.0218, 0.0183, 0.0165, 0.0198, 0.2137, 0.2888, 0.2313, 0.15, 0.2542, 0.2538, 0.2358, 0.1195, 0.1591, 0.2599, 0.2742, 0.1447, 0.2328, 0.1878, 0.1988, 0.1645, 0.1218, 0.2005, 0.2828, 0.2051, 0.1664, 0.1181, 0.1621, 0.2966, 0.189, 0.246, 0.2445, 0.1621, 0.1618, 0.189, 0.2354, 0.1561, 0.1638, 0.2799, 0.0923, 0.1659, 0.1675, 0.1268, 0.0984, 0.0997, 0.1248, 0.1495, 0.1431, 0.1236, 0.1755, 0.1183, 0.1349, 0.1018, 0.1109, 0.1833, 0.1813, 0.1422, 0.0961, 0.1191, 0.0791, 0.0631, 0.0315, 0.0157, 0.0166, 0.0108
]);
(taken from main.js http://wavesurfer-js.org/example/audio-element/main.js on the example here http://wavesurfer-js.org/example/audio-element/)
But it appears that react-wavesurfer doesn't allow this? From what I can gather it will only pass the audio file into the wavesurfer.load, without an option to also pass the waveform. Is there any chance you could add in that extra argument? or is this already possible and i'm missing something?
Hey,
resizing before playing does not occurs.
When I tried to call the resize function it retrieved NaN because it does not have a position.
_secToPos(sec) {
return (1 / this._wavesurfer.getDuration()) * sec;
}
}
1/0 = NaN
It can be fixed by returning 0 when the player doesn't have a duration yet.
Hi,
I have an issue with loading a local file. I am completely new to React. I used Wavesurfer.js before without bigger problmes. I just cannot wrap my head around this...
Here is the code (simply used the template):
import React from 'react';
// import ReactDOM from 'react-dom';
import Wavesurfer from 'react-wavesurfer';
require('wavesurfer.js');
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
playing: false,
pos: 0
};
this.handleTogglePlay = this.handleTogglePlay.bind(this);
this.handlePosChange = this.handlePosChange.bind(this);
}
handleTogglePlay() {
this.setState({
playing: !this.state.playing
});
}
handlePosChange(e) {
this.setState({
pos: e.originalArgs[0]
});
}
render() {
return (
<Wavesurfer
audioFile={'./audio_source/04/lang_wort.mp3'}
pos={this.state.pos}
onPosChange={this.handlePosChange}
playing={this.state.playing}
/>
);
}
}
Thanks for reading,
Rakesh
(edited by @mspae for proper code formatting)
when building and running the example it does not show no region
Hey,
When "playing" prop is true by default, player doesn't start playing until second render.
During componentDidMount, there is not check for playing prop, and play() isn't called on underlying _wavesurfer instance. The result is that the player isn't playing until the next render, where componentWillReceiveProps is calling the play() function.
Also, before play() (or pause()) is called wavesurfer's ready event is never raised.
Omer
It will be nice to have the microphone plugin available to use.
First off, Thank you so much for your work on this! I've been using wavesurfer in one of my react projects and your component has made life easier.
I would like to add regions to my player and I've have had trouble importing the plugin. Heres what I've been doing:
import Wavesurfer, { Regions } from 'react-wavesurfer'
This doesn't recognize Regions further down the page. I've also tried:
import Wavesurfer from 'react-wavesurfer'
import Regions from 'react-wavesurfer/src/plugins/regions'
Any ideas?
Thanks again.
Use case:
I don't know if anyone here has had this issue, but there is a problem when you try to load large files in Chrome, it can cause an out of memory exception. The audio files that I have are sometimes over an hour long.
Now, I know this is a problem in Wavesurfer itself, there are issues on Wavesurfer Github with potential solutions, mostly using predefined peaks or images, but I can't seem to make any one of them work with react-wavesurfer.
Has anyone managed to resolve that problem using react-wavesurfer?
If I try to load audio peaks, it breaks and won't load the audio, and there doesn't seem to be an option to use images like in just Wavesurfer.
I'm fine with just disabling the waveform generation for larger files now, if anyone has managed to do it here, until I can make a better solution.
Hello, I'm trying to use react-wavesurfer with one of my react components. I'm using webpack, so when I try the import statement:
import Wavesurfer from 'react-wavesurfer';
I get a server-side error:
ReferenceError: window is not defined
I checked the component I don't see it available unless I am missing something?
I'm getting this error here:
key: 'componentWillReceiveProps', // 116
value: function componentWillReceiveProps(nextProps) { // 117
// cache reference to old regions // 118
var oldRegions = Object.create(this.props.wavesurfer.regions.list);
I'm following the code examples exactly:
<Wavesurfer
audioFile={this.props.url}
options={wavesurferOptions}
onLoading={e => this.onLoading(e.originalArgs[0])}
onReady={this.onReady}
>
<Regions
regions={this.state.regions}
onSingleRegionUpdate={_ => console.log('region update')}
onRegionClick={_ => console.log('region click')}
/>
</Wavesurfer>
The state is initialized as:
this.state = {
loadProgress: 0,
ready: false,
regions: {
snippet: {
id: 'snippet',
start: 0,
end: 40,
},
},
};
Hi, I would like to use the waveform equalizer. How can I do?
thanks
Introduction method
import Timeline from 'react-wavesurfer/lib/plugins/timeline';
error:
React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components
Getting the following error:
Cannot read property 'visitClass' of undefined
Seems to be a babel-eslint bug, and just need to update:
babel/babel-eslint#243
Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
From https://facebook.github.io/react/docs/typechecking-with-proptypes.html:
Note: React.PropTypes is deprecated as of React v15.5. Please use the prop-types library instead.
Should be a pretty easy fix:
import PropTypes from 'prop-types';
Hi there,
Is there any way I can access the region-created event from wavesurfer.js's regions plugin?
Thanks
Hello, first and foremost thanks for the easy to use package. I have one issue though, as of right now when I resize the browser window during playback the wavesurfer always stops playing. Is this normal? If not, could you let me know how I could avoid this?
Hello,
How can we call api functions such as setVolume(newVolume)?
I attempted to follow the README, and have tried both using npm to install and import the beta version of wavesurfer, as well as simply requiring the cdn-hosted wavesurferjs file into my main project. Either way i continue to get the same error. Not sure what i'm doing wrong here, but it seems others are having the same issue
any idea what i'm doing wrong here?
import WavesurferComponent from 'react-wavesurfer'
...
render() {
<WavesurferComponent audioFile={'/audio/default.mp3'} />
}
// index.ejs
<script src="//cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/1.3.7/wavesurfer.min.js"></script>
render() {
<WavesurferComponent audioFile={'/audio/default.mp3'} />
}
I'm pretty pumped I found this since I'm converting an application to React and didn't think I'd find a React Component for wavesurfer.
What's the current status of the component? Anything I could possibly do?
I noticed some stuff is very different between the two folders, e.g. there's no enableDragSelection
function in src, but there is in lib.
In the wavesurfer.js
gitter chat someone asks:
If I want to display a bunch of waveforms on a page
and have a central player instance [what do I do?]
His solution is to have one single page-wide instance of a player which will sync with the currently selected track (and waveform)
. That seems to make sense. From issue #10 I can see how to get a reference of the wavesurfer
object, but I'm not quite sure how to create dummy players with this lib. I want one smart wavesurfer obj which can have global state and then a bunch of dummy players which modify that global state. How might this be achieved?
I have tried to achieve this leader -> follower relationship by simply creating two components which share state as follows:
<Wavesurfer
audioFile={demoAudio}
pos={this.state.pos}
onPosChange={this.handlePosChange}
playing={this.state.playing}
/>
<Wavesurfer
audioFile={demoAudio}
pos={this.state.pos}
onPosChange={this.handlePosChange}
playing={false}
/>
However, what happens here is there are some subtle audio glitches (pops in the background). I tried removing wavesurfer 2
's onPosChange
property and this fixed the issue! However, that meant that you could no longer control wavesurfer 1
with wavesurfer 2
's visualization. I'll keep updating as I get closer to solving this issue.
It would be useful if the readme could clarify how to import and use the plugins. Whilst the included examples cover the plugins, they're imported locally rather than through npm. I'm sure it's pretty simple to import, but so far everything I've tried hasn't worked.
Hi there,
I am using the regions plugin and came across a problem with updating the regions on state change.
I have two buttons, one for increasing the start value of the region, the other for decreasing it. However, once I click either of the buttons and thus change the state, the region does not update.
Is there any way this can be done?
Thanks
Lately i've been going through my components to try to find which ones are re-rendering unnecessarily. Upon testing a component that had react-wavesurfer in it I found that during playback it re-renders at an extremely high rate. I'm still new to react and i'm wondering if this is a performance issue? Would having 10-20 tracks on a page be extremely inefficient?
Hi,
Thanks for this project.
I'm trying to use this component after 'npm install react-wavesurfer' it says
Cannot find module "wavesurfer.js"
and after a npm i wavesurfer.js i'm getting a window is not defined...
Any Idea on how to make it work?
Thx.
My wave HTML element shows up on the page if I inspect elements but it starts of with an initial width of 0px. Even if I change the width of the div, it still remains hidden. Further, if I resize the screen, I get the following error:
Uncaught TypeError: Cannot read property 'length' of undefined
Any thoughts on how to fix this problem and get my waveform showing?
When the responsive
prop is set, the wavform is redrawn on resize. The called drawBuffer
method does not clear the canvas, though, before redrawing. This causes the waveform to look a bit less crisp once the viewport has been resized.
Looking at the history of the relevant code snippet I see the following:
There once was a call to the empty
method, which was removed at some point to improve handling of pre-rendered peaks.
I do not understand the details of this change yet, but it looks to me as though empty
did too much in the first place. It not only clears the canvas, but also resets player progress etc.
That is also why, I guess, a prior change set out to preserve player progress by manually seeking to the previous position again. All of this appears to be unnecessary now that the empty()
call has been removed.
Looking at the code of wavesurfer.js, it looks like clearing the canvas could be done by calling
this._wavesurfer.drawer.clearWave();
This, of course, reaches into the internals of wavesufer way too much, which is why I have open an issue there to suggest the addition of a redraw
method, as a safe way to redraw the the waveform.
Changing the pos property after player's initial load is not changing the audio's cursor position.
in reference to #6
I have a project in webpack and I can't get regions plugin working. I get this error: "wavesurfer.addRegion is not a function"
Probably I'm getting something wrong but I can't find any examples of plugin use in a webpack project.
It will be nice to have some examples as I guide so it's easier to use.
I've spent hours debugging this without being able to track down exactly what's going on or WHY it's not working the way it should.
Essentially what the issue comes down to is that it appears that ComponentWillReceiveProps isn't firing within the react-wavesurfer plugins/regions component.
In my testing I believe it has something to do with the regions component being a child component inside of the Wavesurfer component.
Here's what my component looks like:
<WaveSurfer
audioFile={this.props.audioFile}
options={waveOptions}
playing={this.state.playing}
pos={this.state.pos}
onReady={(e)=>this.handleOnReady(e)}
onPosChange={(e)=>this.handlePosChange(e)}
onSeek={()=>this.handleSeek()}
regions={this.state.regions}
>
<Regions
regions={this.state.regions}
/>
</WaveSurfer>
this.state.regions
is being set dynamically via setState once I receive start and end region information via an API.
However, this never makes it's way down to the Regions component. I've confirmed by console.logging inside of the ComponentWillReceiveProps method within the react-wavesurfer Regions component.
If I move the regions component to a top level component (of course this has other side effects and breaks other things) , ComponentWillReceiveProps successfully fires.
Essentially the real issue i'm trying to solve is dynamically loading region information. Because this isn't available when the component initially loads and this issue exists, the region never appears.
If you have any suggestions, workarounds, or explanations as to why ComponentWillReceiveProps isn't firing within the Regions component, I'd really appreciate it. I'm stumped...
Let me know what else I can do to help track down the issue. Happy to submit a PR once we track down the root cause.
Oh and I'm running React 15.6.1
I just downloaded the code and I am trying to run using npm start run. Its throwing below error. Can anyone help me for the execution.
ERROR in multi main
Module not found: Error: Cannot resolve module 'run' in C:\Users\kparupati\Downloads\react-wavesurfer-master
@ multi main
ERROR in ./src/plugins/regions.js
Module not found: Error: Cannot resolve 'file' or 'directory' ../../src/plugin/wavesurfer.regions.js in C:\Users\kparupati\Downloads\react-wavesurfer-master\src\plugins
@ ./src/plugins/regions.js 19:0-49
ERROR in ./src/plugins/minimap.js
Module not found: Error: Cannot resolve 'file' or 'directory' ../../src/plugin/wavesurfer.minimap.js in C:\Users\kparupati\Downloads\react-wavesurfer-master\src\plugins
@ ./src/plugins/minimap.js 19:0-49
ERROR in ./src/plugins/timeline.js
Module not found: Error: Cannot resolve module 'wavesurfer.js/dist/plugin/wavesurfer.timeline.js' in C:\Users\kparupati\Downloads\react-wavesurfer-master\src\plugins
@ ./src/plugins/timeline.js 27:0-96
webpack: Failed to compile.
I understand that adding another dependency to the package might not be a popular move. Still I wanted to post a link to a branch that I'm using which replaces a bunch of code in this project with a rather straightforward usage of react-measure
.
Since react-measure
relies on resize and mutation observers, responsive resizing also works if one of the parent elements changes its size while window remains unchanged. This was a requirement in my case.
The branch is an extension of the changes proposed in #48.
Hello,
I've noticed that when I resize the browser window containing the react-wavesurfer component I hear clicks and crackles during audio playback. I'm guessing it might have to do with how the waveform is trying to redraw itself? Is there a work-around for this?
Hi there,
I'm wondering how I would go about using all of wavesurfer methods from within your port. For example, I'd like to use getDuration(), but am not sure how to access the waveform object?
ref: http://wavesurfer-js.org/docs/methods.html
Also to be able to redraw the waveform as explained here:
katspaugh/wavesurfer.js#131
Thanks :)
I am having trouble implementing the Regions plugin. The console does not throw any errors, but no regions are visible, and no region functions fire. I'd really appreciate any suggestions about where to look for the problem.
The component code is:
var React = require('react');
import { connect } from 'react-redux';
import WaveSurfer from 'react-wavesurfer';
window.WaveSurfer = require('wavesurfer.js');
const Regions = require('react-wavesurfer/lib/plugins/regions.js').default;
class SongCard extends React.Component {
constructor(props) {
super(props);
this.state = {
playing: false,
pos: 0,
regions: {}
}
this.handleTogglePlay = this.handleTogglePlay.bind(this);
this.handlePosChange = this.handlePosChange.bind(this);
this.togglePlay = this.togglePlay.bind(this);
this.handleReady = this.handleReady.bind(this);
this.handleRegionUpdated = this.handleRegionUpdated.bind(this);
}
handleTogglePlay() {
this.setState({
playing: !this.state.playing
});
}
handleRegionUpdated(args) {
console.log('in handleRegionUpdated');
}
togglePlay() {
this.setState({
playing: !this.state.playing
});
}
handleReady({ wavesurfer, originalArgs}) {
this.setState({
regions: {
eom: {
id: 'eom',
start: 2,
end: 29,
color: "rgb(0,0,150)"
}
}
});
wavesurfer.enableDragSelection({});
}
render () {
return (
<div>
<div className="container markupRow">
<div className="row">
<button type="button" className="btn btn-primary" onClick={this.togglePlay}>Play/Pause</button>
</div>
</div>
<div className="col-md-8">
<WaveSurfer
audioFile={this.props.song.audioFileUrl}
pos={this.state.pos}
onPosChange={this.handlePosChange}
playing={this.state.playing}
onReady={this.handleReady}
>
<Regions regions={this.state.regions} onRegionUpdated={this.handleRegionUpdated} />
</WaveSurfer>
</div>
</div>
);
}
};
function mapStateToProps(state) {
return {
}
}
function mapDispatchToProps(dispatch) {
return {
}
}
export default connect(mapStateToProps, mapDispatchToProps)(SongCard);
Thanks SO much for this library -- it is really great.
I cloned the repo and ran the examples - they look great!
I would really like to use react-wavesurfer in my project.
I installed both of them using npm, this is how my package.json looks:
"react-wavesurfer": "^0.8.3",
"wavesurfer.js": "^1.1.11"
And expose it using Webpack as described.
Using the simple.js file from the example folder in my component I get this Error & Warning:
WARNING in ./~/source-map-loader!./~/wavesurfer.js/dist/wavesurfer.min.js
(Emitted value instead of an instance of Error) Cannot find SourceMap 'wavesurfer.min.js.map': Error: Can't resolve './wavesurfer.min.js.map' in '/home/mele/dummy_start_page/frontend/node_modules/wavesurfer.js/dist'
@ ./~/wavesurfer.js/dist/wavesurfer.min.js 3:40-149
@ ./src/app/components/DetailView/simple.js
@ ./src/app/components/DetailView/DetailView.js
@ ./src/app/components/App.js
@ ./src/app/index.tsx
@ multi react-hot-loader/patch ./src/app/index.tsx
WARNING in ./~/source-map-loader!./~/wavesurfer.js/dist/wavesurfer.min.js
(Emitted value instead of an instance of Error) Cannot find SourceMap 'wavesurfer.min.js.map': Error: Can't resolve './wavesurfer.min.js.map' in '/home/mele/dummy_start_page/frontend/node_modules/wavesurfer.js/dist'
@ ./~/wavesurfer.js/dist/wavesurfer.min.js 3:40-149
@ ./src/app/components/DetailView/simple.js
@ ./src/app/components/DetailView/DetailView.js
@ ./src/app/components/App.js
@ ./src/app/index.tsx
@ multi react-hot-loader/patch ./src/app/index.tsx
ERROR in ./~/react-wavesurfer/lib/react-wavesurfer.min.js
Module not found: Error: Can't resolve 'wavesurfer' in '/home/mele/dummy_start_page/frontend/node_modules/react-wavesurfer/lib'
@ ./~/react-wavesurfer/lib/react-wavesurfer.min.js 6:270-304
@ ./src/app/components/DetailView/simple.js
@ ./src/app/components/DetailView/DetailView.js
@ ./src/app/components/App.js
@ ./src/app/index.tsx
@ multi react-hot-loader/patch ./src/app/index.tsx
I dont understand what I am missing, would be grateful for any hint...
I am having trouble provoking a re-rendering of the regions when the props change. Here is a simple example:
var React = require('react');
import WaveSurfer from 'react-wavesurfer';
window.WaveSurfer = require('wavesurfer.js');
let Regions = require('./Regions').default;
class SongCard extends React.Component {
constructor(props) {
super(props);
this.state = {
playing: false,
pos: 0,
regions: {
eoi: {
id: 'eoi',
start: 5,
end: 6
}
}
};
this.togglePlay = this.togglePlay.bind(this);
this.handleTogglePlayClick = this.handleTogglePlayClick.bind(this);
this.handlePosChange = this.handlePosChange.bind(this);
this.handleMoveRegionsClick = this.handleMoveRegionsClick.bind(this);
}
togglePlay() {
this.setState({
playing: !this.state.playing
});
}
handleTogglePlayClick() {
this.togglePlay();
}
handlePosChange({ wavesurfer, originalArgs}) {
this.setState({
pos: originalArgs[0]
})
}
handleMoveRegionsClick() {
const newState = Object.assign({}, this.state, {
regions: {
eoi: {
start: this.state.regions.eoi.start+10,
end: this.state.regions.eoi.end+10,
id: 'eoi'
}
}
});
this.setState(newState);
}
render () {
return (
<div>
<div>
<button type="button" className="btn btn-primary btn-xs" onClick={this.handleMoveRegionsClick}>Change Region</button>
</div>
<WaveSurfer
audioFile={'https://ia902606.us.archive.org/35/items/shortpoetry_047_librivox/song_cjrg_teasdale_64kb.mp3'}
pos={this.state.pos}
onPosChange={this.handlePosChange}
playing={this.state.playing}
>
<Regions regions={this.state.regions} />
</WaveSurfer>
</div>
);
}
};
export default SongCard;
When I call setState() within handleMoveRegionsClick(), SongCard's state is updated, but it does not trigger a reload of the Region's props.
Could anyone point me in the right direction for how to solve this? Thanks!
Here's the error:
Uncaught DOMException: Failed to execute 'stop' on 'AudioScheduledSourceNode': cannot call stop without calling start first.
Any ideas?
Hello, I cannot implement enableDragSelection to add new regions, can anyone help me?
Hi,
it would be great if we could use a gradient for waveColor option (as it happens at the top of wavesurfer-js.org page)
doing this
var ctx = document.createElement('canvas').getContext('2d');
var linGrad = ctx.createLinearGradient(0, 64, 0, 200);
linGrad.addColorStop(0.5, 'white');
linGrad.addColorStop(0.5, 'crimson');
<Wavesurfer
options={{barHeight:4, barWidth:2, waveColor:linGrad }}
audioFile={`someaudio.mp4`}
/>
Works for me but a warning is thrown as the "waveColor" property is expected to be a string.
Keep getting this error after updating to 0.8.5, the error points to the setVolume function in wavesurfer.min.js.
Can I get any help with this please?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.