Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,365 @@
|
||||
import moduleHelper from '../module-helper';
|
||||
import { isSupportPlayBackRate } from '../../check-version';
|
||||
import { audios, localAudioMap, downloadingAudioMap } from './store';
|
||||
import { createInnerAudio, destroyInnerAudio, printErrMsg } from './utils';
|
||||
import { IGNORE_ERROR_MSG, INNER_AUDIO_UNDEFINED_MSG } from './const';
|
||||
const funs = {
|
||||
|
||||
getFullUrl(v) {
|
||||
if (!/^https?:\/\//.test(v) && !/^wxfile:\/\//.test(v)) {
|
||||
const cdnPath = GameGlobal.manager.assetPath;
|
||||
v = `${cdnPath.replace(/\/$/, '')}/${v.replace(/^\//, '').replace(/^Assets\//, '')}`;
|
||||
}
|
||||
return v;
|
||||
},
|
||||
|
||||
downloadAudios(paths) {
|
||||
const list = paths.split(',');
|
||||
return Promise.all(list.map((v) => {
|
||||
const src = funs.getFullUrl(v);
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (!downloadingAudioMap[src]) {
|
||||
downloadingAudioMap[src] = [
|
||||
{
|
||||
resolve,
|
||||
reject,
|
||||
},
|
||||
];
|
||||
if (funs.checkLocalFile(src)) {
|
||||
funs.handleDownloadEnd(src, true);
|
||||
}
|
||||
else if (!GameGlobal.unityNamespace.isCacheableFile(src)) {
|
||||
|
||||
wx.downloadFile({
|
||||
url: src,
|
||||
success(res) {
|
||||
if (res.statusCode === 200 && res.tempFilePath) {
|
||||
localAudioMap[src] = res.tempFilePath;
|
||||
funs.handleDownloadEnd(src, true);
|
||||
}
|
||||
else {
|
||||
funs.handleDownloadEnd(src, false);
|
||||
}
|
||||
},
|
||||
fail(e) {
|
||||
funs.handleDownloadEnd(src, false);
|
||||
printErrMsg(e);
|
||||
},
|
||||
});
|
||||
}
|
||||
else {
|
||||
const xmlhttp = new GameGlobal.unityNamespace.UnityLoader.UnityCache.XMLHttpRequest();
|
||||
xmlhttp.open('GET', src, true);
|
||||
xmlhttp.responseType = 'arraybuffer';
|
||||
xmlhttp.onsave = () => {
|
||||
localAudioMap[src] = GameGlobal.manager.getCachePath(src);
|
||||
funs.handleDownloadEnd(src, true);
|
||||
};
|
||||
xmlhttp.onsavefail = () => {
|
||||
funs.handleDownloadEnd(src, false);
|
||||
};
|
||||
xmlhttp.onerror = () => {
|
||||
funs.handleDownloadEnd(src, false);
|
||||
};
|
||||
xmlhttp.send();
|
||||
}
|
||||
}
|
||||
else {
|
||||
downloadingAudioMap[src].push({
|
||||
resolve,
|
||||
reject,
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
},
|
||||
|
||||
handleDownloadEnd(src, succeeded) {
|
||||
if (!downloadingAudioMap[src]) {
|
||||
return;
|
||||
}
|
||||
while (downloadingAudioMap[src] && downloadingAudioMap[src].length > 0) {
|
||||
const item = downloadingAudioMap[src].shift();
|
||||
if (!succeeded) {
|
||||
item?.reject();
|
||||
}
|
||||
else {
|
||||
item?.resolve('');
|
||||
}
|
||||
}
|
||||
delete downloadingAudioMap[src];
|
||||
},
|
||||
// 是否存在本地文件
|
||||
checkLocalFile(src) {
|
||||
if (localAudioMap[src]) {
|
||||
return true;
|
||||
}
|
||||
const path = GameGlobal.manager.getCachePath(src);
|
||||
if (path) {
|
||||
localAudioMap[src] = path;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
// 设置路径
|
||||
setAudioSrc(audio, getSrc) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const src = funs.getFullUrl(getSrc);
|
||||
// 设置原始路径,后面用此路径作为key值
|
||||
audio.isLoading = src;
|
||||
if (funs.checkLocalFile(src)) {
|
||||
audio.src = localAudioMap[src];
|
||||
delete audio.isLoading;
|
||||
funs.handleDownloadEnd(src, true);
|
||||
resolve(localAudioMap[src]);
|
||||
}
|
||||
else if (audio.needDownload) {
|
||||
funs
|
||||
.downloadAudios(src)
|
||||
.then(() => {
|
||||
if (audio) {
|
||||
audio.src = localAudioMap[src];
|
||||
delete audio.isLoading;
|
||||
resolve(localAudioMap[src]);
|
||||
}
|
||||
else {
|
||||
console.warn('资源已被删除:', src);
|
||||
reject({
|
||||
errCode: -1,
|
||||
errMsg: '资源已被删除',
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.warn('资源下载失败:', src);
|
||||
if (audio) {
|
||||
audio.src = src;
|
||||
delete audio.isLoading;
|
||||
}
|
||||
reject({
|
||||
errCode: -1,
|
||||
errMsg: '资源下载失败',
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
// 不推荐这样处理,建议优先下载再使用,除非是需要立即播放的长音频文件或一次性播放音频
|
||||
// console.warn('建议优先下载再使用:', src);
|
||||
audio.src = src;
|
||||
delete audio.isLoading;
|
||||
resolve(src);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
function checkHasAudio(id) {
|
||||
if (audios[id]) {
|
||||
return true;
|
||||
}
|
||||
console.error(INNER_AUDIO_UNDEFINED_MSG, id);
|
||||
return false;
|
||||
}
|
||||
export default {
|
||||
// 创建audio对象
|
||||
WXCreateInnerAudioContext(src, loop, startTime, autoplay, volume, playbackRate, needDownload) {
|
||||
const { audio: getAudio, id } = createInnerAudio();
|
||||
getAudio.needDownload = needDownload;
|
||||
if (src) {
|
||||
// 设置原始src
|
||||
funs.setAudioSrc(getAudio, src).catch((e) => {
|
||||
moduleHelper.send('OnAudioCallback', JSON.stringify({
|
||||
callbackId: id,
|
||||
errMsg: 'onError',
|
||||
result: JSON.stringify(e),
|
||||
}));
|
||||
});
|
||||
}
|
||||
if (loop) {
|
||||
getAudio.loop = true;
|
||||
}
|
||||
if (autoplay) {
|
||||
getAudio.autoplay = true;
|
||||
}
|
||||
if (typeof startTime === 'undefined') {
|
||||
startTime = 0;
|
||||
}
|
||||
if (startTime > 0) {
|
||||
getAudio.startTime = +startTime.toFixed(2);
|
||||
}
|
||||
if (typeof volume === 'undefined') {
|
||||
volume = 1;
|
||||
}
|
||||
if (volume !== 1) {
|
||||
getAudio.volume = +volume.toFixed(2);
|
||||
}
|
||||
|
||||
if (!isSupportPlayBackRate) {
|
||||
playbackRate = 1;
|
||||
}
|
||||
if (typeof playbackRate !== 'undefined' && playbackRate !== 1) {
|
||||
getAudio.playbackRate = +playbackRate.toFixed(2);
|
||||
}
|
||||
return id;
|
||||
},
|
||||
|
||||
WXInnerAudioContextSetBool(id, k, v) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
audios[id][k] = Boolean(+v);
|
||||
},
|
||||
|
||||
WXInnerAudioContextSetString(id, k, v) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (k === 'src') {
|
||||
funs.setAudioSrc(audios[id], v);
|
||||
}
|
||||
else if (k === 'needDownload') {
|
||||
audios[id].needDownload = !!v;
|
||||
}
|
||||
else {
|
||||
audios[id][k] = v;
|
||||
}
|
||||
},
|
||||
|
||||
WXInnerAudioContextSetFloat(id, k, v) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
audios[id][k] = +v.toFixed(2);
|
||||
},
|
||||
|
||||
WXInnerAudioContextGetFloat(id, k) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return 0;
|
||||
}
|
||||
return audios[id][k];
|
||||
},
|
||||
|
||||
WXInnerAudioContextGetBool(id, k) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return false;
|
||||
}
|
||||
return audios[id][k];
|
||||
},
|
||||
WXInnerAudioContextPlay(id) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = audios[id].isLoading;
|
||||
if (url) {
|
||||
if (downloadingAudioMap[url]) {
|
||||
downloadingAudioMap[url].push({
|
||||
resolve: () => {
|
||||
if (typeof audios[id] !== 'undefined') {
|
||||
audios[id].play();
|
||||
}
|
||||
},
|
||||
reject: () => { },
|
||||
});
|
||||
}
|
||||
else {
|
||||
audios[id].src = url;
|
||||
audios[id].play();
|
||||
}
|
||||
}
|
||||
else {
|
||||
audios[id].play();
|
||||
}
|
||||
},
|
||||
WXInnerAudioContextPause(id) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
audios[id].pause();
|
||||
},
|
||||
WXInnerAudioContextStop(id) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
audios[id].stop();
|
||||
},
|
||||
WXInnerAudioContextDestroy(id) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
destroyInnerAudio(id, false);
|
||||
},
|
||||
WXInnerAudioContextSeek(id, position) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
audios[id].seek(+position.toFixed(3));
|
||||
},
|
||||
|
||||
WXInnerAudioContextAddListener(id, key) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
if (key === 'onCanplay') {
|
||||
audios[id][key](() => {
|
||||
|
||||
|
||||
|
||||
const { duration, buffered, referrerPolicy, volume } = audios[id];
|
||||
setTimeout(() => {
|
||||
moduleHelper.send('OnAudioCallback', JSON.stringify({
|
||||
callbackId: id,
|
||||
errMsg: key,
|
||||
}));
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
else if (key === 'onError') {
|
||||
audios[id][key]((e) => {
|
||||
if (key === 'onError') {
|
||||
console.error(e);
|
||||
|
||||
if (e.errMsg && e.errMsg.indexOf(IGNORE_ERROR_MSG) > -1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
moduleHelper.send('OnAudioCallback', JSON.stringify({
|
||||
callbackId: id,
|
||||
errMsg: key,
|
||||
result: JSON.stringify(e),
|
||||
}));
|
||||
});
|
||||
}
|
||||
else {
|
||||
audios[id][key](() => {
|
||||
moduleHelper.send('OnAudioCallback', JSON.stringify({
|
||||
callbackId: id,
|
||||
errMsg: key,
|
||||
}));
|
||||
});
|
||||
}
|
||||
},
|
||||
WXInnerAudioContextRemoveListener(id, key) {
|
||||
if (!checkHasAudio(id)) {
|
||||
return;
|
||||
}
|
||||
audios[id][key]();
|
||||
},
|
||||
WXPreDownloadAudios(paths, id) {
|
||||
funs
|
||||
.downloadAudios(paths)
|
||||
.then(() => {
|
||||
moduleHelper.send('WXPreDownloadAudiosCallback', JSON.stringify({
|
||||
callbackId: id.toString(),
|
||||
errMsg: '0',
|
||||
}));
|
||||
})
|
||||
.catch(() => {
|
||||
moduleHelper.send('WXPreDownloadAudiosCallback', JSON.stringify({
|
||||
callbackId: id.toString(),
|
||||
errMsg: '1',
|
||||
}));
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user