react-app-shell
Version:
react打包脚本和example, 这里的版本请忽略
150 lines (127 loc) • 3.24 kB
JavaScript
import { observable, action } from 'mobx';
import preloader from 'preloader';
// let timer = null;
// const TIMEOUT_DELAY = 300;
class AudioStore {
// 正在活跃的音频,音频唯一标识。
activeId = null;
// 资源列表
resource = {};
/**
* 初始化音频资源列表
* @param urls 音频url, 数组
*/
init = (urls) => {
if (!Array.isArray(urls)) {
console.error('AudioStore >>> init >>> 参数格式错误');
return;
}
const resource = {};
urls.forEach((url) => {
resource[url] = {
url, // 原始url
localUrl: '', // 本地url
isPreload: false, // 是否与加载
isPlayed: false // 是否播放过
};
});
this.resource = resource;
};
/**
* 预加载音频文件
* @returns {Promise<void>}
*/
preloadAudio = async (url) => {
const audio = this.resource[url];
if (!audio || audio.isPreload) {
return;
}
audio.isPreload = true;
const loader = preloader({});
try {
const promise = new Promise((resolve, reject) => {
loader.addAudio(url);
// 加载完
loader.on('complete', () => {
const resource = {};
const localResource = loader.get(url);
resource[url] = {
url,
localUrl: (localResource && localResource.src) || url,
isPreload: true,
isPlayed: true // 是否播放过
};
resolve(resource);
});
// 启动预加载
loader.load();
});
const resource = await promise;
this.resource = {
...this.resource,
...resource
};
} catch (error) {
console.error(error);
}
};
/**
* 音频资源地址, 默认是原始资源地址, 点击播放一次之后 会下载到本地, 更新为 本地音频资源地址
* @param url
* @returns {*}
*/
getLocalUrl = (url) => {
// 获取本地url
const localUrl = this.resource[url] && this.resource[url]['localUrl'];
return localUrl || url;
};
/**
* 播放功能
* 如果 没有播放的音频, 直接播放
* 如果 url === 当前播放的音频, 则暂停播放
* 如果 url !== 当前播放的音频, 则先暂停, 再播放 url
* @param url 资源地址
*/
playAudio = (url) => {
const audio = this.resource[url];
if (!audio) {
return;
}
audio.isPlayed = true;
if (!url) {
console.error('没有要播放的资源');
return;
}
// 没有播放的音频, 直接播放
if (!this.activeId) {
this.activeId = url;
this.preloadAudio(url);
return;
}
// 如果 url === 当前播放的音频, 则暂停播放
if (this.activeId === url) {
// 停止播放播放
this.activeId = null;
return;
}
// 如果 url !== 当前播放的音频, 则先暂停, 再播放 url
if (this.activeId && this.activeId !== url) {
this.activeId = url;
this.preloadAudio(url);
return;
}
};
/**
* 播放完成
*/
playFinish = () => {
this.activeId = null;
};
}
export default new AudioStore();