APlayer 中文文档 下载 App

APlayer 自定义音频类型扩展

核心思路

APlayer 内置了对原生 HTML5 Audio 和 HLS 的支持。但浏览器能解码的音频格式不止这些——WebM、Opus、AAC 容器变化、甚至私有流媒体协议都可以通过 customAudioType 来接入。

思路是:告诉 Aplayer "遇到 type: 'xxx' 的音频时,调用这个回调函数来处理加载和播放"。

配置结构

const ap = new APlayer({
    container: document.getElementById('aplayer'),
    audio: [{
        name: '歌曲名称',
        url: 'audio-url',
        type: 'customType1'  // 自定义类型标识
    }],
    customAudioType: {
        'customType1': function(audioElement, audio, player) {
            // 在这里处理加载逻辑
            // audioElement 是原生 HTMLAudioElement
            // audio 是这个音频的配置对象
            // player 是 APlayer 实例
        }
    }
});

customAudioType 是一个对象,键是你自定义的类型名,值是回调函数。

回调函数参数

参数类型说明
audioElementHTMLAudioElement原生 audio 元素,设置它的 src 就能播放
audioobject当前音频的完整配置对象(包含 name、artist、url、cover 等)
playerAPlayerAPlayer 实例,可调用 notice、theme 等方法

示例一:最简单的自定义(等效 type: 'normal')

customAudioType: {
    'myAudio': function(audioElement, audio, player) {
        audioElement.src = audio.url;
    }
}

这和直接不写 type(type: 'auto')效果一样,但你可以在里面额外做点事情,比如 URL 转换、认证头等。

示例二:带重试的网络电台

customAudioType: {
    'radio': function(audioElement, audio, player) {
        let retryCount = 0;
        const maxRetries = 3;

        function load() {
            audioElement.src = audio.url;
        }

        audioElement.addEventListener('error', function() {
            if (retryCount < maxRetries) {
                retryCount++;
                player.notice(`连接失败,第 ${retryCount} 次重试...`, 2000);
                setTimeout(load, 2000);
            } else {
                player.notice('连接失败,已重试 3 次', 3000);
            }
        });

        load();
    }
}

示例三:先下载再播放

某些场景下你可能需要先处理一下音频内容再播放:

customAudioType: {
    'preloaded': function(audioElement, audio, player) {
        fetch(audio.url)
            .then(res => res.blob())
            .then(blob => {
                const objectUrl = URL.createObjectURL(blob);
                audioElement.src = objectUrl;

                // 播放结束后释放
                audioElement.addEventListener('ended', () => {
                    URL.revokeObjectURL(objectUrl);
                }, { once: true });
            });
    }
}

这种方式还能配合 Service Worker 实现离线缓存。

与 type: 'auto' 的关系

audio.type 值APlayer 内部行为
'auto'(默认)直接把 url 赋给 audioElement
'hls'用 Hls 处理(需要 window.Hls)
其他字符串去 customAudioType 里找同名的回调

所以自定义类型名不能是 'auto'、'normal'、'hls'——这些被 APlayer 占用了。

与 HLS customAudioType 的关系

上一页 HLS 流媒体 里已经展示过用 customAudioType 接入 HLS 的例子。这里再总结一下:customAudioType 比 type: 'hls' 更灵活,可以自定义 HLS 配置、错误处理、降级策略等。

清理资源

如果你的自定义类型创建了额外资源(如 Blob URL、第三方播放器实例),记得在播放器销毁或歌曲切换时清理:

// 在回调函数内部保存引用
let hlsInstance = null;

customAudioType: {
    'myHls': function(audioElement, audio, player) {
        hlsInstance = new Hls();
        hlsInstance.loadSource(audio.url);
        hlsInstance.attachMedia(audioElement);
    }
}

// 在 destroy 事件里清理
ap.on('destroy', function() {
    if (hlsInstance) {
        hlsInstance.destroy();
        hlsInstance = null;
    }
});