npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wq-audio-player

v1.1.1

Published

功能强大的HTML5音频播放器,支持Vue/React、频谱可视化、进度拖拽、试听模式、资源保护等高级功能

Readme

WQ Audio Player

一个功能强大、美观的HTML5音频播放器,支持Vue、React等框架,内置频谱可视化、试听模式、国际化、缓存进度显示等高级功能。

✨ 功能特性

  • 🎨 美观的毛玻璃效果UI设计,支持自定义主题色
  • 🎵 实时音频频谱可视化效果(环形声浪+底部频谱)
  • 🎚️ 进度条拖拽功能,支持长按圆圈自由调整播放进度
  • ⏯️ 完整播放控制(播放/暂停、快退/快进15秒、音量调节)
  • ⚡ 倍速播放(0.5x - 2x)
  • 🔁 重新播放功能
  • 🖥️ 全屏播放支持
  • ⏱️ 试听模式,可限制播放时长
  • 💰 试听结束自定义购买按钮
  • 🌍 内置国际化支持(简体中文/英文)
  • 📦 缓存进度实时显示
  • 📱 响应式设计,适配移动端触摸操作
  • ⌨️ 键盘快捷键支持(空格键播放/暂停)
  • 🔧 高度可配置,支持跨域设置
  • 🔌 支持原生JS、Vue、React等所有前端框架
  • 🔒 内置资源保护:自动将音频转为Blob URL,隐藏原始音频地址
  • 🕵️ Audio元素深度隐藏,大幅提升音频资源被盗取的难度

📦 安装

npm安装

npm install wq-audio-player --save

CDN引入

<link rel="stylesheet" href="https://unpkg.com/wq-audio-player/dist/style.css">
<script src="https://unpkg.com/wq-audio-player/dist/index.js"></script>

🚀 基础使用

原生JavaScript

<div id="audio-player"></div>

<script>
const player = new WqAudioPlayer('#audio-player', {
  audioUrl: 'https://example.com/audio.mp3',
  coverUrl: 'https://example.com/cover.jpg',
  title: '歌曲名称',
  artist: '歌手名称',
  previewSeconds: 10, // 试听10秒
  showPurchaseButton: true, // 显示购买按钮
  language: 'zh-CN' // 中文界面
});

// 监听事件
player.on('play', () => console.log('开始播放'));
player.on('purchase', () => window.location.href = '/buy');
</script>

ES6模块导入

import WqAudioPlayer from 'wq-audio-player';
import 'wq-audio-player/dist/style.css';

const player = new WqAudioPlayer('#player-container', {
  audioUrl: '你的音频地址.mp3',
  title: '歌曲名称',
  width: '500px',
  musicColor: '#409eff'
});

⚙️ 完整配置项

| 参数名 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | audioUrl | string | '' | 音频地址(必填) | | coverUrl | string | 'https://picsum.photos/seed/music/400/400' | 专辑封面地址 | | title | string | 'Unknown Title' | 歌曲标题 | | showTitle | boolean | true | 是否显示歌曲标题 | | artist | string | 'Unknown Artist' | 歌手名称 | | showArtist | boolean | false | 是否显示歌手名称 | | autoplay | boolean | false | 是否自动播放(受浏览器策略限制) | | width | string | '100%' | 播放器宽度 | | height | string | 'auto' | 播放器高度 | | previewSeconds | number | 0 | 试听时长(秒),0表示不限制 | | showPurchaseButton | boolean | false | 试听结束后是否显示购买按钮 | | purchaseButtonText | string | undefined | 购买按钮自定义文字,默认使用当前语言翻译 | | purchaseButtonBgColor | string | '#409eff' | 购买按钮背景色 | | purchaseButtonTextColor | string | '#ffffff' | 购买按钮文字颜色 | | cvHeight | string | '200px' | 频谱画布高度 | | musicColor | string | '#fff' | 频谱波形颜色 | | speedOptions | array | [0.5, 0.75, 1, 1.25, 1.5, 2] | 倍速可选值列表 | | crossOrigin | string/boolean | 'anonymous' | 音频跨域配置,可选值:'anonymous''use-credentials'false | | language | string | 'zh-CN' | 界面语言,支持:'zh-CN'(简体中文)、'en-US'(英文) | | showCircularWave | boolean | true | 是否显示碟片环形声浪效果 | | showBottomWave | boolean | false | 是否显示底部频谱音浪效果 | | t | function | 内置翻译函数 | 自定义翻译函数,用于扩展多语言 | | onPlay | function | undefined | 播放事件回调 | | onPause | function | undefined | 暂停事件回调 | | onEnded | function | undefined | 播放结束回调 | | onPreviewEnded | function | undefined | 试听结束回调 | | onSeek | function | undefined | 进度跳转回调 | | onPurchase | function | undefined | 购买按钮点击回调 | | onError | function | undefined | 音频加载错误回调 |

🎧 事件回调

| 事件名 | 说明 | 回调参数 | |--------|------|----------| | play | 开始播放时触发 | - | | pause | 暂停播放时触发 | - | | ended | 播放结束时触发 | - | | previewEnded | 试听结束时触发 | - | | seek | 拖动进度条跳转播放时触发 | currentTime(跳转后的时间点,秒) | | purchase | 点击购买按钮时触发 | - | | error | 音频加载错误时触发 | errorInfo(错误信息对象,包含错误类型和提示) |

事件监听示例

// 监听播放事件
player.on('play', () => {
  console.log('音频开始播放');
});

// 监听错误事件
player.on('error', (error) => {
  console.error('音频加载失败:', error);
  if (error.type === 'cors') {
    alert('音频跨域访问被限制,请检查服务器配置');
  }
});

// 监听购买按钮点击
player.on('purchase', () => {
  // 跳转到购买页面
  window.location.href = '/buy-audio';
});

🛠️ 实例方法

| 方法名 | 说明 | 参数 | |--------|------|------| | togglePlay() | 切换播放/暂停状态 | - | | handleBackward() | 后退15秒 | - | | handleForward() | 前进15秒 | - | | setPlaybackRate(rate) | 设置播放倍速 | rate: 倍速值 | | toggleMute() | 切换静音状态 | - | | toggleLoop() | 重新播放(回到开始位置并播放) | - | | handleFullscreen() | 切换全屏模式 | - | | setAudioUrl(url) | 切换音频地址 | url: 新的音频地址 | | on(eventName, callback) | 监听事件 | eventName: 事件名, callback: 回调函数 | | destroy() | 销毁播放器实例,释放资源 | - |

🔌 框架集成

Vue 3 使用示例

<template>
  <div ref="playerRef"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import WqAudioPlayer from 'wq-audio-player';
import 'wq-audio-player/dist/style.css';

const playerRef = ref(null);
let player = null;

onMounted(() => {
  player = new WqAudioPlayer(playerRef.value, {
    audioUrl: 'https://example.com/audio.mp3',
    title: 'Vue3项目示例',
    previewSeconds: 10,
    showPurchaseButton: true
  });

  player.on('play', () => {
    console.log('播放开始');
  });
});

onUnmounted(() => {
  player?.destroy();
});
</script>

Vue 2 使用示例

<template>
  <div ref="playerRef"></div>
</template>

<script>
import WqAudioPlayer from 'wq-audio-player';
import 'wq-audio-player/dist/style.css';

export default {
  data() {
    return {
      player: null
    }
  },
  mounted() {
    this.player = new WqAudioPlayer(this.$refs.playerRef, {
      audioUrl: 'https://example.com/audio.mp3',
      title: 'Vue2示例'
    });
  },
  beforeDestroy() {
    this.player?.destroy();
  }
}
</script>

React 使用示例

import { useEffect, useRef } from 'react';
import WqAudioPlayer from 'wq-audio-player';
import 'wq-audio-player/dist/style.css';

const AudioPlayer = () => {
  const playerRef = useRef(null);
  const playerInstance = useRef(null);

  useEffect(() => {
    if (!playerInstance.current && playerRef.current) {
      playerInstance.current = new WqAudioPlayer(playerRef.current, {
        audioUrl: 'https://example.com/audio.mp3',
        title: 'React项目示例',
        language: 'en-US' // 英文界面
      });

      playerInstance.current.on('purchase', () => {
        console.log('跳转到购买页面');
      });
    }

    return () => {
      playerInstance.current?.destroy();
      playerInstance.current = null;
    };
  }, []);

  return <div ref={playerRef}></div>;
};

export default AudioPlayer;

🌍 国际化

切换语言

const player = new WqAudioPlayer('#player', {
  // ...其他配置
  language: 'en-US' // 切换为英文界面
});

自定义多语言

const player = new WqAudioPlayer('#player', {
  // ...其他配置
  language: 'ja-JP',
  t: function(key, params) {
    // 自定义日语翻译
    const translations = {
      'audio.albumCover': 'アルバムカバー',
      'audio.previewEnded': '試聴終了',
      'audio.previewDescription': '試聴が終了しました。完全版を購入してください。試聴時間: {seconds}秒',
      'audio.purchaseButton': '購入する'
    };
    let text = translations[key] || key;
    if (params) {
      Object.keys(params).forEach(k => {
        text = text.replace(`{${k}}`, params[k]);
      });
    }
    return text;
  }
});

⌨️ 键盘快捷键

  • 空格键:播放/暂停(播放器聚焦时有效)

❓ 常见问题

1. 音频加载跨域错误

Access to audio at 'xxx' from origin 'xxx' has been blocked by CORS policy

解决方法

  • 配置音频资源服务器的CORS规则,允许你的域名访问
  • 如果是阿里云OSS,需要在控制台配置跨域规则:
    • 允许Methods:GETHEADOPTIONS
    • 允许Headers:*
    • 暴露Headers:ETagContent-LengthContent-RangeAccept-Ranges
  • 如果不需要频谱功能,可以设置crossOrigin: false,可以绕过跨域限制正常播放

2. 自动播放不生效

浏览器安全策略限制音频自动播放,需要用户交互(如点击页面)后才能自动播放,可以在用户点击事件回调中调用player.togglePlay()触发播放。

3. 频谱不显示

需要确保:

  • 音频地址配置了正确的CORS规则
  • crossOrigin参数设置为'anonymous'
  • 音频格式是浏览器支持的格式(mp3/wav/ogg等)

4. 关于音频资源保护

播放器内置的Blob转码和元素隐藏功能,可以:

  • ✅ 隐藏原始音频URL,用户在DOM中只能看到blob:开头的临时地址
  • ✅ 防止普通用户直接获取和分享原始音频链接
  • ✅ Blob URL仅在当前页面上下文有效,关闭页面或刷新后立即失效
  • ❌ 无法100%防止专业技术人员通过抓包等方式获取音频(完全防下载需要服务端配合实现加密流媒体)

如果需要更高等级的版权保护,建议配合服务端实现:

  • 音频URL签名和过期机制
  • Referer防盗链校验
  • HLS流媒体AES加密

浏览器兼容性

支持现代浏览器,需要支持以下API:

  • AudioContext
  • requestAnimationFrame
  • requestFullscreen
  • ES6+语法

更新日志

v1.1.1

  • 🔧 新增 ES5 兼容性构建,通过 Babel 转译支持不支持 ES6 的老项目
  • 📦 默认输出指向 ES5 版本,保持源码版本同时提供向后兼容
  • ✅ 完全兼容 Vue 2 / Vue 3 / React 等所有前端框架
  • 提供多种格式输出:UMD, CommonJS, ES Module

v1.1.0

  • ✨ 新增进度条拖拽功能,支持长按圆圈自由调整播放进度
  • ✨ 拖拽过程中实时显示时间,进度条不被自动更新影响
  • ✨ 支持鼠标和移动端触摸操作
  • ✨ 拖拽时鼠标样式动态变化(手掌/抓手)
  • ✨ 新增频谱显示开关配置:showCircularWaveshowBottomWave
  • 🐛 优化拖拽交互体验,兼容试听时长限制
  • ✨ 新增音频资源保护功能,自动将音频转为Blob URL隐藏原始地址
  • 🐛 优化Blob资源释放逻辑,避免内存泄漏
  • 🐛 新增加载失败降级机制,当Blob加载失败时自动使用原始URL

📄 许可证

MIT License