You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MediaElementJS切换流媒体后pause事件触发导致isPlaying状态异常求助

问题:MediaElementJS v7切换音频流时isPlaying被错误置为false

使用MediaElementJS v7实现网络电台切换功能时,点击切换新流后,新流可正常播放,但旧流的pause事件会在新流的play事件之后触发,导致全局变量isPlaying被错误设置为false。

原实现代码

$(document).on('click', '.header a[rel=open_player]', function() {
    var bottom_player = $(document).find('.bottom-player');
    var webradio_id = $(this).attr('data-id');
    isPlaying = true;
    var currentStream;

    $.post('/ajax/webradio/'+ webradio_id, function(data) {
        bottom_player.html(data);
        var player = bottom_player.find('audio');
        
        player.mediaelementplayer({
            audioWidth: '100%',
            pluginPath: '/assets/public/js/mediaelement/',
            alwaysShowControls: true,
            features: ['playpause','volume'],
            audioVolume: 'horizontal',
            isVideo: false,
            forceLive: true,
            success: function (mediaElement, domObject) {
                mediaElement.play();
                currentStream = mediaElement.getSrc();
                mediaElement.addEventListener('play', function () {
                    console.log('['+Date.now() + '] Media play: getSrc='+ mediaElement.getSrc()+' / currentStream='+currentStream);
                    document.title = '▶ ' + origTitle;
                    isPlaying = true;
                }, false);
                mediaElement.addEventListener('pause', function () {
                    if(currentStream == mediaElement.getSrc()) {
                         console.log('['+Date.now() + '] Media pause: getSrc='+ mediaElement.getSrc() + ' / currentStream='+currentStream);
                         document.title = origTitle;
                         isPlaying = false;
                     }
                }, false);
            },
        });
    });
});

控制台日志示例

[1695287178446] Media play: getSrc=https://example.com/stream-wr03.aac?i=94884 / currentStream=https://example.com/stream-wr03.aac?i=94884
[1695287178449] Media pause: getSrc=https://example.com/stream-01.aac?i=30130 / currentStream=https://example.com/stream-01.aac?i=30130
[1695287190405] Media play: getSrc=https://example.com/stream-wr01.aac?i=24717 / currentStream=https://example.com/stream-wr01.aac?i=24717
[1695287190409] Media pause: getSrc=https://example.com/stream-wr03.aac?i=94884 / currentStream=https://example.com/stream-wr03.aac?i=94884

解决方案

核心问题是旧的MediaElement实例未被销毁,其事件监听仍在触发。以下是两种可行的修复方案:

方案1:全局跟踪活跃实例并清理旧实例

每次切换流时,先销毁之前的播放器实例,避免旧事件继续触发;通过全局变量跟踪当前活跃实例,确保pause事件只处理当前正在播放的流。

// 全局变量跟踪当前活跃的播放器实例
let activeMediaElement = null;

$(document).on('click', '.header a[rel=open_player]', function() {
    var bottom_player = $(document).find('.bottom-player');
    var webradio_id = $(this).attr('data-id');
    
    // 清理旧实例:暂停播放、移除事件监听、销毁实例
    if (activeMediaElement) {
        activeMediaElement.pause();
        activeMediaElement.remove();
        activeMediaElement = null;
    }
    
    isPlaying = true;

    $.post('/ajax/webradio/'+ webradio_id, function(data) {
        bottom_player.html(data);
        var player = bottom_player.find('audio');
        
        player.mediaelementplayer({
            audioWidth: '100%',
            pluginPath: '/assets/public/js/mediaelement/',
            alwaysShowControls: true,
            features: ['playpause','volume'],
            audioVolume: 'horizontal',
            isVideo: false,
            forceLive: true,
            success: function (mediaElement, domObject) {
                activeMediaElement = mediaElement;
                mediaElement.play();
                const currentStream = mediaElement.getSrc();
                
                mediaElement.addEventListener('play', function () {
                    console.log('['+Date.now() + '] Media play: getSrc='+ mediaElement.getSrc()+' / currentStream='+currentStream);
                    document.title = '▶ ' + origTitle;
                    isPlaying = true;
                }, false);
                
                mediaElement.addEventListener('pause', function () {
                    // 仅当当前实例是活跃实例时,才更新状态
                    if (mediaElement === activeMediaElement) {
                        console.log('['+Date.now() + '] Media pause: getSrc='+ mediaElement.getSrc() + ' / currentStream='+currentStream);
                        document.title = origTitle;
                        isPlaying = false;
                    }
                }, false);
            },
        });
    });
});

方案2:块级作用域变量+实例标记

如果不想使用全局变量,可通过块级作用域变量结合元素dataset标记当前流,确保事件判断的准确性:

$(document).on('click', '.header a[rel=open_player]', function() {
    var bottom_player = $(document).find('.bottom-player');
    var webradio_id = $(this).attr('data-id');
    
    // 销毁旧实例
    const oldPlayer = bottom_player.find('audio').data('mediaelementplayer');
    if (oldPlayer) {
        oldPlayer.remove();
    }
    
    isPlaying = true;

    $.post('/ajax/webradio/'+ webradio_id, function(data) {
        bottom_player.html(data);
        var player = bottom_player.find('audio');
        
        player.mediaelementplayer({
            audioWidth: '100%',
            pluginPath: '/assets/public/js/mediaelement/',
            alwaysShowControls: true,
            features: ['playpause','volume'],
            audioVolume: 'horizontal',
            isVideo: false,
            forceLive: true,
            success: function (mediaElement, domObject) {
                mediaElement.play();
                const currentStream = mediaElement.getSrc();
                // 给当前实例标记流地址
                mediaElement.dataset.streamSrc = currentStream;
                
                mediaElement.addEventListener('play', function () {
                    console.log('['+Date.now() + '] Media play: getSrc='+ mediaElement.getSrc()+' / currentStream='+currentStream);
                    document.title = '▶ ' + origTitle;
                    isPlaying = true;
                }, false);
                
                mediaElement.addEventListener('pause', function () {
                    // 判断暂停的流是否为当前跟踪的流
                    if (mediaElement.dataset.streamSrc === currentStream) {
                        console.log('['+Date.now() + '] Media pause: getSrc='+ mediaElement.getSrc() + ' / currentStream='+currentStream);
                        document.title = origTitle;
                        isPlaying = false;
                    }
                }, false);
            },
        });
    });
});

内容的提问来源于stack exchange,提问作者Guillaume

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 19:15:05