diff --git a/demo/demo.js b/demo/demo.js
index 9b5e189..81e6488 100644
--- a/demo/demo.js
+++ b/demo/demo.js
@@ -96,6 +96,13 @@ const ap4 = new APlayer({
cover: 'https://moeplayer.b0.upaiyun.com/aplayer/yourname.jpg',
lrc: 'https://moeplayer.b0.upaiyun.com/aplayer/yourname.lrc',
theme: '#505d6b'
+ }, {
+ name: '光るなら(HLS)',
+ artist: 'Goose house',
+ url: 'https://moeplayer.b0.upaiyun.com/aplayer/hls/hikarunara.m3u8',
+ cover: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.jpg',
+ theme: '#ebd0c2',
+ type: 'hls'
}]
});
@@ -135,4 +142,44 @@ ap5.on('switchaudio', (index) => {
ap5.theme(`rgb(${color[0]}, ${color[1]}, ${color[2]})`, index);
});
}
+});
+
+const ap6 = new APlayer({
+ element: document.getElementById('player6'),
+ mutex: true,
+ audio: [{
+ name: '光るなら(HLS)',
+ artist: 'Goose house',
+ url: 'https://moeplayer.b0.upaiyun.com/aplayer/hls/hikarunara.m3u8',
+ cover: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.jpg',
+ theme: '#ebd0c2',
+ type: 'hls'
+ }]
+});
+const ap7 = new APlayer({
+ element: document.getElementById('player7'),
+ mutex: true,
+ audio: [{
+ name: '光るなら(HLS)',
+ artist: 'Goose house',
+ url: 'https://moeplayer.b0.upaiyun.com/aplayer/hls/hikarunara.m3u8',
+ cover: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.jpg',
+ theme: '#ebd0c2',
+ 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.');
+ }
+ }
+ }
});
\ No newline at end of file
diff --git a/demo/index.html b/demo/index.html
index a9c7368..51683ab 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -43,8 +43,9 @@
font-size: 18px;
}
-
-
+
+
+
@@ -91,6 +92,9 @@
Narrow
+
HLS
+
+
diff --git a/docs/README.md b/docs/README.md
index c8e95a2..a2b4331 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -81,6 +81,8 @@ audio.url | - | audio url
audio.cover | - | audio cover
audio.lrc | - | [see more details](https://aplayer.js.org/#/home?id=lrc)
audio.theme | - | main color when switching to this audio, it has priority over the above theme
+audio.type | 'auto' | values: 'auto', 'hls', 'normal' or other custom type, [see more details](https://aplayer.js.org/#/home?id=mse-support)
+customAudioType | - | [see more details](https://aplayer.js.org/#/home?id=mse-support)
mutex | true | prevent to play multiple player at the same time, pause other players when this player start play
lrcType | 0 | [see more details](https://aplayer.js.org/#/home?id=lrc)
listFolded | false | indicate whether list should folded at first
@@ -411,12 +413,71 @@ const ap = new APlayer({
});
```
+## MSE support
+
+### HLS
+
+It requires the library [hls.js](https://github.com/video-dev/hls.js) and it should be loaded before `APlayer.min.js`.
+
+
+
+```html
+
+
+
+
+```
+
+```js
+const ap = new APlayer({
+ container: document.getElementById('aplayer'),
+ audio: [{
+ name: 'HLS',
+ artist: 'artist',
+ url: 'url.m3u8',
+ cover: 'cover.jpg',
+ type: 'hls'
+ }]
+});
+```
+
+```js
+// another way, use customType
+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.');
+ }
+ }
+ }
+});
+```
+
## Self-adapting theme according to cover
It requires the library [color-thief](https://github.com/lokesh/color-thief/blob/master/src/color-thief.js).
-
Click to load player
+
Click to load player
```html
diff --git a/docs/config.js b/docs/config.js
index ddf6d62..d44371d 100644
--- a/docs/config.js
+++ b/docs/config.js
@@ -219,7 +219,39 @@ function aplayer6 () {
function aplayer7 () {
window.ap7 = new APlayer({
- container: document.getElementById('aplayer7'),
+ container: document.getElementById('player7'),
+ audio: [{
+ name: '光るなら(HLS)',
+ artist: 'Goose house',
+ url: 'https://moeplayer.b0.upaiyun.com/aplayer/hls/hikarunara.m3u8',
+ cover: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.jpg',
+ theme: '#ebd0c2',
+ type: 'hls'
+ }, {
+ name: '光るなら',
+ artist: 'Goose house',
+ url: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.mp3',
+ cover: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.jpg',
+ theme: '#ebd0c2'
+ }, {
+ name: 'トリカゴ',
+ artist: 'XX:me',
+ url: 'https://moeplayer.b0.upaiyun.com/aplayer/darling.mp3',
+ cover: 'https://moeplayer.b0.upaiyun.com/aplayer/darling.jpg',
+ theme: '#46718b'
+ }, {
+ name: '前前前世',
+ artist: 'RADWIMPS',
+ url: 'https://moeplayer.b0.upaiyun.com/aplayer/yourname.mp3',
+ cover: 'https://moeplayer.b0.upaiyun.com/aplayer/yourname.jpg',
+ theme: '#505d6b'
+ }]
+ });
+}
+
+function aplayer8 () {
+ window.ap8 = new APlayer({
+ container: document.getElementById('aplayer8'),
theme: '#e9e9e9',
audio: [{
name: '光るなら',
@@ -240,10 +272,10 @@ function aplayer7 () {
});
const colorThief = new ColorThief();
- window.ap7.on('switchaudio', function (index) {
- if (!window.ap7.options.audio[index].theme) {
- colorThief.getColorAsync(window.ap7.options.audio[index].cover, function (color) {
- window.ap7.theme(`rgb(${color[0]}, ${color[1]}, ${color[2]})`, index);
+ window.ap8.on('switchaudio', function (index) {
+ if (!window.ap8.options.audio[index].theme) {
+ colorThief.getColorAsync(window.ap8.options.audio[index].cover, function (color) {
+ window.ap8.theme(`rgb(${color[0]}, ${color[1]}, ${color[2]})`, index);
});
}
});
diff --git a/docs/zh-Hans/README.md b/docs/zh-Hans/README.md
index da02e9f..b136505 100644
--- a/docs/zh-Hans/README.md
+++ b/docs/zh-Hans/README.md
@@ -82,6 +82,8 @@ audio.url | - | 音频链接
audio.cover | - | 音频封面
audio.lrc | - | [详情](https://aplayer.js.org/#/home?id=lrc)
audio.theme | - | 切换到此音频时的主题色,比上面的 theme 优先级高
+audio.type | 'auto' | 可选值: 'auto', 'hls', 'normal' 或其他自定义类型, [详情](https://aplayer.js.org/#/home?id=mse-support)
+customAudioType | - | 自定义类型,[详情](https://aplayer.js.org/#/home?id=mse-support)
mutex | true | 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
lrcType | 0 | [详情](https://aplayer.js.org/#/home?id=lrc)
listFolded | false | 列表默认折叠
@@ -412,12 +414,71 @@ const ap = new APlayer({
});
```
+## MSE 支持
+
+### HLS
+
+需要在 `APlayer.min.js` 前面加载 [hls.js](https://github.com/video-dev/hls.js)。
+
+
+
+```html
+
+
+
+
+```
+
+```js
+const ap = new APlayer({
+ container: document.getElementById('aplayer'),
+ audio: [{
+ name: 'HLS',
+ artist: 'artist',
+ url: 'url.m3u8',
+ cover: 'cover.jpg',
+ type: 'hls'
+ }]
+});
+```
+
+```js
+// 另一种方式,使用 customAudioType
+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](https://github.com/lokesh/color-thief/blob/master/src/color-thief.js)
```html
diff --git a/src/js/options.js b/src/js/options.js
index 70779d6..6d3920b 100644
--- a/src/js/options.js
+++ b/src/js/options.js
@@ -30,6 +30,7 @@ export default (options) => {
item.name = item.name || item.title;
item.artist = item.artist || item.author;
item.cover = item.cover || item.pic;
+ item.type = item.type || 'normal';
return item;
});
diff --git a/src/js/player.js b/src/js/player.js
index 055a5b3..cf905ed 100644
--- a/src/js/player.js
+++ b/src/js/player.js
@@ -200,16 +200,17 @@ class APlayer {
this.playIndex = index;
}
+ const audio = this.options.audio[this.playIndex];
// set html
- if (this.options.audio[this.playIndex].cover) {
- this.template.pic.style.backgroundImage = `url('${this.options.audio[this.playIndex].cover}')`;
+ if (audio.cover) {
+ this.template.pic.style.backgroundImage = `url('${audio.cover}')`;
}
else {
this.template.pic.style.backgroundImage = '';
}
this.theme();
- this.template.title.innerHTML = this.options.audio[this.playIndex].name;
- this.template.author.innerHTML = this.options.audio[this.playIndex].artist ? ' - ' + this.options.audio[this.playIndex].artist : '';
+ this.template.title.innerHTML = audio.name;
+ this.template.author.innerHTML = audio.artist ? ' - ' + audio.artist : '';
const light = this.container.getElementsByClassName('aplayer-list-light')[0];
if (light) {
light.classList.remove('aplayer-list-light');
@@ -218,7 +219,47 @@ class APlayer {
this.template.list.scrollTop = this.playIndex * 33;
- this.audio.src = this.options.audio[this.playIndex].url;
+ // mse
+ if (this.hls) {
+ this.hls.destroy();
+ this.hls = null;
+ }
+ let type = audio.type;
+ if (this.options.customAudioType && this.options.customAudioType[type]) {
+ if (Object.prototype.toString.call(this.options.customAudioType[type]) === '[object Function]') {
+ this.options.customAudioType[type](this.audio, audio, this);
+ }
+ else {
+ console.error(`Illegal customType: ${type}`);
+ }
+ }
+ else {
+ if (!type || type === 'auto') {
+ if (/m3u8(#|\?|$)/i.exec(audio.url)) {
+ type = 'hls';
+ }
+ else {
+ type = 'normal';
+ }
+ }
+ if (type === 'hls') {
+ if (Hls.isSupported()) {
+ this.hls = new Hls();
+ this.hls.loadSource(audio.url);
+ this.hls.attachMedia(this.audio);
+ }
+ else if (this.audio.canPlayType('application/x-mpegURL') || this.audio.canPlayType('application/vnd.apple.mpegURL')) {
+ this.audio.src = audio.url;
+ }
+ else {
+ this.notice('Error: HLS is not supported.');
+ }
+ }
+ else if (type === 'normal') {
+ this.audio.src = audio.url;
+ }
+ }
+
this.seek(0);
let playPromise;