APlayer
🍭 Wow, such a beautiful HTML5 music player
特别赞助商
安装
使用 npm:
使用 Yarn:
入门
1 2 3
| <link rel="stylesheet" href="APlayer.min.css"> <div id="aplayer"></div> <script src="APlayer.min.js"></script>
|
1 2 3 4 5 6 7 8 9
| const ap = new APlayer({ container: document.getElementById('aplayer'), audio: [{ name: 'name', artist: 'artist', url: 'url.mp3', cover: 'cover.jpg' }] });
|
使用模块管理器:
1 2 3 4
| import 'APlayer/dist/APlayer.min.css'; import APlayer from 'APlayer';
const ap = new APlayer(options);
|
参数
| 名称 |
默认值 |
描述 |
| container |
document.querySelector(‘.aplayer’) |
播放器容器元素 |
| fixed |
false |
开启吸底模式, 详情 |
| mini |
false |
开启迷你模式, 详情 |
| autoplay |
false |
音频自动播放 |
| theme |
‘#b7daff’ |
主题色 |
| loop |
‘all’ |
音频循环播放, 可选值: ‘all’, ‘one’, ‘none’ |
| order |
‘list’ |
音频循环顺序, 可选值: ‘list’, ‘random’ |
| preload |
‘auto’ |
预加载,可选值: ‘none’, ‘metadata’, ‘auto’ |
| volume |
0.7 |
默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效 |
| audio |
- |
音频信息, 应该是一个对象或对象数组 |
| audio.name |
- |
音频名称 |
| audio.artist |
- |
音频艺术家 |
| audio.url |
- |
音频链接 |
| audio.cover |
- |
音频封面 |
| audio.lrc |
- |
详情 |
| audio.theme |
- |
切换到此音频时的主题色,比上面的 theme 优先级高 |
| audio.type |
‘auto’ |
可选值: ‘auto’, ‘hls’, ‘normal’ 或其他自定义类型, 详情 |
| customAudioType |
- |
自定义类型,详情 |
| mutex |
true |
互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器 |
| lrcType |
0 |
详情 |
| listFolded |
false |
列表默认折叠 |
| listMaxHeight |
- |
列表最大高度 |
| storageName |
‘aplayer-setting’ |
存储播放器设置的 localStorage key |
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const ap = new APlayer({ container: document.getElementById('player'), mini: false, autoplay: false, theme: '#FADFA3', loop: 'all', order: 'random', preload: 'auto', volume: 0.7, mutex: true, listFolded: false, listMaxHeight: 90, lrcType: 3, audio: [ { name: 'name1', artist: 'artist1', url: 'url1.mp3', cover: 'cover1.jpg', lrc: 'lrc1.lrc', theme: '#ebd0c2' }, { name: 'name2', artist: 'artist2', url: 'url2.mp3', cover: 'cover2.jpg', lrc: 'lrc2.lrc', theme: '#46718b' } ] });
|
API
APlayer.version: 静态属性, 返回 APlayer 的版本号
ap.play(): 播放音频
ap.pause(): 暂停音频
ap.seek(time: number): 跳转到特定时间,时间的单位为秒
ap.toggle(): 切换播放和暂停
ap.on(event: string, handler: function): 绑定音频和播放器事件,详情
ap.volume(percentage: number, nostorage: boolean): 设置音频音量
ap.theme(color: string, index: number): 设置播放器主题色, index 默认为当前音频的 index
ap.setMode(mode: string): 设置播放器模式,mode 取值应为 ‘mini’ 或 ‘normal’
ap.mode: 返回播放器当前模式,’mini’ 或 ‘normal’
ap.notice(text: string, time: number, opacity: number): 显示通知,时间的单位为毫秒,默认时间 2000 毫秒,默认透明度 0.8,设置时间为 0 可以取消通知自动隐藏
1
| ap.notice('Amazing player', 2000, 0.8);
|
ap.skipBack(): 切换到上一首音频
ap.skipForward(): 切换到下一首音频
ap.destroy(): 销毁播放器
ap.lrc
ap.lrc.show(): 显示歌词
ap.lrc.hide(): 隐藏歌词
ap.lrc.toggle(): 显示/隐藏歌词
ap.list
1 2 3 4 5 6 7 8
| ap.list.add([{ name: 'name', artist: 'artist', url: 'url.mp3', cover: 'cover.jpg', lrc: 'lrc.lrc', theme: '#ebd0c2' }]);
|
ap.list.remove(index: number): 移除播放列表中的一个音频
ap.list.switch(): 切换到播放列表里的其他音频
ap.audio: 原生 audio
ap.audio.currentTime: 返回音频当前播放时间
ap.audio.duration: 返回音频总时间
ap.audio.paused: 返回音频是否暂停
支持大多数原生audio接口
事件绑定
ap.on(event, handler)
1 2 3
| ap.on('ended', function () { console.log('player ended'); });
|
音频事件
- abort
- canplay
- canplaythrough
- durationchange
- emptied
- ended
- error
- loadeddata
- loadedmetadata
- loadstart
- mozaudioavailable
- pause
- play
- playing
- progress
- ratechange
- seeked
- seeking
- stalled
- suspend
- timeupdate
- volumechange
- waiting
播放器事件
- listshow
- listhide
- listadd
- listremove
- listswitch
- listclear
- noticeshow
- noticehide
- destroy
- lrcshow
- lrchide
歌词
我们有三种方式来给 APlayer 传递歌词,使用 lrcType 参数指明使用哪种方式,然后把歌词放到 audio.lrc 参数或者 HTML 里。
LRC 文件方式
第一种方式,把歌词放到 LRC 文件里,音频播放时会加载对应的 LRC 文件。
1 2 3 4 5 6 7 8 9 10 11
| const ap = new APlayer({ container: document.getElementById('aplayer'), lrcType: 3, audio: { name: 'name', artist: 'artist', url: 'demo.mp3', cover: 'demo.jpg', lrc: 'lrc.lrc' } });
|
JS 字符串方式
第二种方式,把歌词放到 JS 字符串里面。
1 2 3 4 5 6 7 8 9 10 11
| const ap = new APlayer({ container: document.getElementById('aplayer'), lrcType: 1, audio: { name: 'name', artist: 'artist', url: 'demo.mp3', cover: 'demo.jpg', lrc: '[00:00.00]APlayer\n[00:04.01]is\n[00:08.02]amazing' } });
|
HTML 方式
第三种方式,把歌词放到 HTML 里面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <link rel="stylesheet" href="APlayer.min.css"> <div id="player"> <pre class="aplayer-lrc-content"> [00:00.00]APlayer audio1 [00:04.01]is [00:08.02]amazing </pre> <pre class="aplayer-lrc-content"> [00:00.00]APlayer audio2 [00:04.01]is [00:08.02]amazing </pre> </div> <script src="APlayer.min.js"></script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const ap = new APlayer({ container: document.getElementById('aplayer'), lrcType: 2, audio: [[ { name: 'name1', artist: 'artist1', url: 'url1.mp3', cover: 'cover1.jpg' }, { name: 'name2', artist: 'artist2', url: 'url2.mp3', cover: 'cover2.jpg' } ]] });
|
歌词格式
支持下面格式的歌词:
[mm:ss]APlayer
[mm:ss.xx]is
[mm:ss.xxx]amazing
[mm:ss.xx][mm:ss.xx]APlayer
[mm:ss.xx]<mm:ss.xx>is
[mm:ss.xx]amazing[mm:ss.xx]APlayer
播放列表
当有多个音频时会 APlayer 会展示一个播放列表,listFolded 参数指明列表是否默认折叠,listMaxHeight 参数指明列表最大高度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const ap = new APlayer({ container: document.getElementById('player'), listFolded: false, listMaxHeight: 90, lrcType: 3, audio: [ { name: 'name1', artist: 'artist1', url: 'url1.mp3', cover: 'cover1.jpg', lrc: 'lrc1.lrc', theme: '#ebd0c2' }, { name: 'name2', artist: 'artist2', url: 'url2.mp3', cover: 'cover2.jpg', lrc: 'lrc2.lrc', theme: '#46718b' } ] });
|
吸底模式
APlayer 可以通过吸底模式固定在页面底部,这种模式跟普通模式有很大不同。
1 2 3 4 5 6 7 8 9 10
| const ap = new APlayer({ container: document.getElementById('player'), fixed: true, audio: [{ name: 'name', artist: 'artist', url: 'url.mp3', cover: 'cover.jpg', }] });
|
迷你模式
如果你没有足够空间来放置正常模式的播放器,那么你可以考虑使用迷你模式。
请注意迷你模式与吸底模式冲突。
1 2 3 4 5 6 7 8 9 10
| const ap = new APlayer({ container: document.getElementById('player'), mini: true, audio: [{ name: 'name', artist: 'artist', url: 'url.mp3', cover: 'cover.jpg', }] });
|
MSE 支持
HLS
需要在 APlayer.min.js 前面加载 hls.js。
1 2 3 4
| <link rel="stylesheet" href="APlayer.min.css"> <div id="aplayer"></div> <script src="hls.min.js"></script> <script src="APlayer.min.js"></script>
|
1 2 3 4 5 6 7 8 9 10
| const ap = new APlayer({ container: document.getElementById('aplayer'), audio: [{ name: 'HLS', artist: 'artist', url: 'url.m3u8', cover: 'cover.jpg', type: 'hls' }] });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const ap = new APlayer({ container: document.getElementById('aplayer'), audio: [{ name: 'HLS', artist: 'artist', url: 'url.m3u8', cover: 'cover.jpg', type: 'customHls' }], customAudioType: { 'customHls': function (audioElement, audio, player) { if (Hls.isSupported()) { const hls = new Hls(); hls.loadSource(audio.url); hls.attachMedia(audioElement); } else if (audioElement.canPlayType('application/x-mpegURL') || audioElement.canPlayType('application/vnd.apple.mpegURL')) { audioElement.src = audio.url; } else { player.notice('Error: HLS is not supported.'); } } } });
|
根据封面自适应主题色
需要额外加载 color-thief.js
1 2 3 4
| <link rel="stylesheet" href="APlayer.min.css"> <div id="aplayer"></div> <script src="APlayer.min.js"></script> <script src="color-thief.js"></script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| const ap = new APlayer({ container: document.getElementById('aplayer'), theme: '#e9e9e9', audio: [{ name: 'name1', artist: 'artist1', url: 'url1.mp3', cover: 'cover1.jpg' }, { name: 'name2', artist: 'artist2', url: 'url2.mp3', cover: 'cover2.jpg' }] });
const colorThief = new ColorThief(); const image = new Image(); const xhr = new XMLHttpRequest(); const setTheme = (index) => { if (!ap.list.audios[index].theme) { xhr.onload = function(){ let coverUrl = URL.createObjectURL(this.response); image.onload = function(){ let color = colorThief.getColor(image); ap.theme(`rgb(${color[0]}, ${color[1]}, ${color[2]})`, index); URL.revokeObjectURL(coverUrl) }; image.src = coverUrl; } xhr.open('GET', ap.list.audios[index].cover, true); xhr.responseType = 'blob'; xhr.send(); } }; setTheme(ap.list.index); ap.on('listswitch', (index) => { setTheme(index); });
|
CDN
常见问题
为什么播放器不能在手机上自动播放?
大多数移动端浏览器禁止了音频自动播放。