Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change src (player.src()) bug that duplicate event fire #151

Open
kjw3898 opened this issue Nov 12, 2021 · 1 comment
Open

change src (player.src()) bug that duplicate event fire #151

kjw3898 opened this issue Nov 12, 2021 · 1 comment
Labels

Comments

@kjw3898
Copy link

kjw3898 commented Nov 12, 2021

Description

I use this plugin on react, and it's nice project. thanks
when I change the src the player, it looks good work.

this.player.src({src: '../media/hal.wav', type: 'audio/wav'});

but it fire event twice.
if change the src once more, it fire event 3times

so I tried to find problem from my project, I found weird console message
when init page ( first src load)

video.min.js:12 VIDEOJS: Using video.js 7.15.4 with videojs-wavesurfer 3.8.0 and wavesurfer.js 5.2.0
webaudio.js:76 
value @ webaudio.js:76
video.min.js:12 VIDEOJS: Using wavesurfer.js MediaElement backend.
video.min.js:12 VIDEOJS: Loading element: [object HTMLAudioElement]
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!

when change src

VIDEOJS: Loading element: [object HTMLAudioElement]   // first load
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!                   
video.min.js:12 VIDEOJS: Loading element: [object HTMLAudioElement] // change src
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Waveform is ready   <-- duplicated ready event fire
index.js:29 waveform: ready!

when change src again

VIDEOJS: Loading element: [object HTMLAudioElement]   // first load
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Loading element: [object HTMLAudioElement]  // change src
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Waveform is ready    <-- duplicated ready event fire
index.js:29 waveform: ready!
VIDEOJS: Loading element: [object HTMLAudioElement]  // change src again
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Waveform is ready    <-- duplicated ready event fire
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Waveform is ready    <-- duplicated ready event fire
index.js:29 waveform: ready!

if you use other event , that also duplicated . eg. playbackFinish

I tried to some workaround for this problem but not work
this.player.wavesurfer().load(item.path) // this code just change src of waveform. not audio(video.js src not changed)

Steps to reproduce

I can reproduce on react example in this repo with little change
change the index.js ( /examples/react/index.js) to below code

/**
 * React example.
 */

class VideojsWavesurferPlayer extends React.Component {
    constructor() {
        super();
        this.clickevt = this.clickevt.bind(this);
    }


    clickevt(){
        this.player.src({src: '../media/hal.wav', type: 'audio/wav'});
    }
    componentDidMount() {
        // instantiate Video.js
        this.player = videojs(this.audioNode, this.props, () => {
            // print version information at startup
            var version_info = 'Using video.js ' + videojs.VERSION +
                ' with videojs-wavesurfer ' + videojs.getPluginVersion('wavesurfer') +
                ' and wavesurfer.js ' + WaveSurfer.VERSION;
            videojs.log(version_info);

            // load file
            this.player.src({src: '../media/hal.wav', type: 'audio/wav'});
        });

        this.player.on('waveReady', (event) => {
            console.log('waveform: ready!');
        });

        this.player.on('playbackFinish', (event) => {
            console.log('playback finished.');
        });

        // error handling
        this.player.on('error', (element, error) => {
            console.warn(error);
        });
    }

    // destroy player on unmount
    componentWillUnmount() {
        if (this.player) {
            this.player.dispose();
        }
    }

    // wrap the player in a div with a `data-vjs-player` attribute
    // so videojs won't create additional wrapper in the DOM
    // see https://github.com/videojs/video.js/pull/3856
    render() {
        return (<div>
            <div data-vjs-player>
                <audio id="myAudio" ref={ node => this.audioNode = node } className="video-js vjs-default-skin"></audio>
            </div>
            <button onClick = {this.clickevt}> click!</button></div>
        )
    }
}

const videoJsOptions = {
    controls: true,
    autoplay: false,
    loop: false,
    muted: false,
    fluid: false,
    width: 600,
    height: 300,
    bigPlayButton: false,
    plugins: {
        wavesurfer: {
            backend: 'MediaElement',
            displayMilliseconds: true,
            debug: true,
            waveColor: 'white',
            progressColor: 'black',
            cursorColor: 'black',
            hideScrollbar: true
        }
    }
};

ReactDOM.render(<VideojsWavesurferPlayer { ...videoJsOptions } />, document.getElementById('root'));

and, open dev tool on web browser, click the button that title is click!
then watch to console log

you'll see the result like this

VIDEOJS: Using wavesurfer.js MediaElement backend.
video.min.js:12 VIDEOJS: Loading element: [object HTMLAudioElement]
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Loading element: [object HTMLAudioElement]
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Loading element: [object HTMLAudioElement]
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!
video.min.js:12 VIDEOJS: Waveform is ready
index.js:29 waveform: ready!

Results

Expected

not duplicate event fire

Actual

duplicated event fire

Versions

Make sure to include the following versions:

videojs/wavesurfer

what version of video.js, videojs-wavesurfer and wavesurfer.js does this occur with?
i checked this issue on
VIDEOJS: Using video.js 7.15.4 with videojs-wavesurfer 3.8.0 and wavesurfer.js 5.2.0 <- example code version
VIDEOJS: Using video.js 7.15.4 with videojs-wavesurfer 3.8.0, wavesurfer.js 5.2.0 and React 17.0.2 <- my project

Browsers OSes

I found this error on windows chrome, edge, and electron. other OS and browser not checked

@thijstriemstra
Copy link
Member

thijstriemstra commented Nov 28, 2021

Thanks for the detailed feedback. I was able to reproduce this without react as well, simply call player.src() at some point, e.g:

player.src({src: 'media/hal.wav', type: 'audio/wav'});

and it triggers the waveReady and playbackFinish events twice. Calling player.src() again results in those events being called three times so there I suspect there is something that doesn't clean up the event listeners properly..

Tested with video.js 7.17.0 with videojs-wavesurfer 3.8.0 and wavesurfer.js 5.2.0 on Firefox 94.0.2, macOS 12.0.1

Looks like it's related to this video.js issue? videojs/video.js#4677

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants