这个问题啥时候解决?
提供下版本号。
我昨天下载的最新的2.0.1 版本 ,发现勾选md5cache 之后 发布到微信里面 音频播放不出来 ,去掉md5cache 发布到微信,就可以。我看播放路径,res/raw-assets/1d/1dd75ba5-d1e5-4306-9524-053faabe62f2.mp3 但是微信里面的真正路径是.//res/raw-assets/1d/1dd75ba5-d1e5-4306-9524-053faabe62f2.aac79.mp3
我这边测试是没问题的。
下面这个链接是发布md5cache的资源版本
.//res/raw-assets/1d/1dd75ba5-d1e5-4306-9524-053faabe62f2.aac79.mp3
你看播放的路径会通过地址转换,转换成md5版链接
res/raw-assets/1d/1dd75ba5-d1e5-4306-9524-053faabe62f2.mp3
不清楚你是在什么情况下无法播放的。
是不是需要自己动手转换地址,我用的是cc.AudioClip应该引擎自动转换的吧
audioSource直接就是AudioClip
代码如下:
play : function(audioSource, loop, callback, isBgMusic) {
if (isBgMusic && !this.mMusicSwitch) return;
if (!isBgMusic && !this.mEffectSwitch) return;
var volume = isBgMusic ? this.bgMusicVolume : this.effectMusicVolume;
if (CC_JSB) {
var context = cc.audioEngine.play(audioSource, loop, volume);
if (callback){
cc.audioEngine.setFinishCallback(context, function(){
callback.call(this);
}.bind(this));
}
this.mAudioMap[audioSource] = context;
cc.wwx.OutPut.log('play audio effect : ' + audioSource);
return audioSource;
} else {
var context = wx.createInnerAudioContext();
context.autoplay = true;
context.loop = loop;
context.obeyMuteSwitch = true;
context.volume = volume;
if (callback) {
context.onEnded(function() {
callback.call(this);
}.bind(this));
} else {
context.offEnded();
}
var audioPath = wxDownloader.REMOTE_SERVER_ROOT + audioSource;
if (audioSource && audioPath != wxDownloader.REMOTE_SERVER_ROOT && audioPath.endsWith('.mp3')) {
context.src = audioPath;
context.play();
this.mAudioMap[audioSource] = context;
}
cc.wwx.OutPut.log('play audio effect : ' + context.src);
return audioSource;
}
},
`文字缩进4格`
使用loadRes去加载音频的话,是不需要转换地址,如果其他原因,上传个demo工程,看起来快。
这个问题应该是使用微信接口 就不行
var context = wx.createInnerAudioContext();
context.autoplay = true;
context.loop = loop;
context.obeyMuteSwitch = true;
context.volume = volume;
if (callback) {
context.onEnded(function() {
callback.call(this);
}.bind(this));
} else {
context.offEnded();
}
var audioPath = wxDownloader.REMOTE_SERVER_ROOT + audioSource;
if (audioSource && audioPath != wxDownloader.REMOTE_SERVER_ROOT && audioPath.endsWith('.mp3')) {
context.src = audioPath;
context.play();
this.mAudioMap[audioSource] = context;
}
我也遇到了相同的问题,使用了微信的接口就会不行,请问你有什么好的解决方案吗?
暂时没有
例如:
第一步:cc.url.raw(resources/audio/click.mp3);
这个是cdn的地址:${cdn}${Const.GameEnName}
let cdn = ‘’; // SDKTools.CdnUrl;
cdn && (url = ${cdn}${Const.GameEnName}/${url});
得到的地址为:res/raw-assets/57/5784bfc1-05eb-47df-bc2a-4d13a3003d5f.mp3
第二步:url = cc.loader.md5Pipe.transformURL(url);
得到url地址为:res/raw-assets/57/5784bfc1-05eb-47df-bc2a-4d13a3003d5f.24503.mp3
如果勾选了md5 cache,一定要用transformURL
Audio.zip (6.2 KB)
在微信小游戏的声音播放上面,归总的audio工具类,可以自由切换使用微信的声音播放api还是cocos自带的api。
解决了勾选了md5 cache以后,使用微信自带的createInnerAudioContext api,播放声音需要指定url,碰到了url转换不正确的问题,通过社区强大的力量找到了解决方案。特提供给碰到类似问题的广大朋友。
执行WxAudio.ts的protected getPath(name: string)方法,运行结果为:
这样就能找到微信小游戏项目目录res/raw-assets/57下面的声音文件咯:
当然如果使用的是cocos自带的声音播放引擎,不会出现类似的问题。
LoaderMgr.ts的封装:
import Helper from ‘…/common/Helper’;
export default class LoaderCenter {
/**已加载资源引用计数, key:资源路径 value:被加载次数 */
private resLoadNumMap: Map<string, number> = null;
private constructor() {
this.resLoadNumMap = new Map;
}
/**
* 加载声音资源
* @param url 资源路径
*/
loadSpriteFrameWithUrl(url: string): Promise<cc.SpriteFrame> {
return new Promise(resolve => {
this.loadResWithUrl(url, cc.SpriteFrame, {
complete: (err: any, res: cc.SpriteFrame) => resolve(res),
context: this
});
});
}
/**
* 加载声音资源
* @param url 资源路径
*/
loadAudioWithUrl(url: string): Promise<cc.AudioClip> {
return new Promise(resolve => {
this.loadResWithUrl(url, cc.AudioClip, {
complete: (err: any, res: cc.AudioClip) => {
resolve(res);
},
context: this
});
});
}
/**
* 加载预制体资源
* @param url 资源路径
*/
loadPrefabWithUrl(url: string): Promise<cc.Prefab> {
return new Promise(resolve => {
this.loadResWithUrl(url, cc.Prefab, {
complete: (err: any, res: cc.Prefab) => {
resolve(res);
},
context: this
});
});
}
/**
* 加载资源
* @param url 资源路径
* @param resType 资源类型
* @param opts
* complete 完成回调,回传参数列表 (error, resource)
* progress 进度回调,回传参数列表 (completedCount, totalCount, item)
*/
loadResWithUrl(url: string, resType: typeof cc.Asset, opts?: { complete: Function, progress?: Function, context?: any }) {
opts = opts || Object.create(null);
let res = cc.loader.getRes(url, resType);
if (cc.isValid(res))
return opts.complete && opts.complete.call(opts.context, null, res);
cc.loader.loadRes(
url,
resType,
(completedCount: number, totalCount: number, item: any) => {
// 进度回调
opts.progress && opts.progress.call(opts.context, completedCount, totalCount, item);
},
(err, res) => {
// 完成回调
if (err) return cc.error('ResManager loadRes Error', err);
opts.complete && opts.complete.call(opts.context, err, res);
// 资源引用计数
let deps = cc.loader.getDependsRecursively(url);
for (let resPath of deps) {
let num = this.resLoadNumMap.get(resPath);
if (num == null) {
this.resLoadNumMap.set(resPath, 1);
} else {
this.resLoadNumMap.set(resPath, num + 1);
}
}
}
);
}
/**
* 释放资源
* @param url
*/
releaseRes(url: string) {
let deps = cc.loader.getDependsRecursively(url);
for (let resPath of deps) {
let num = this.resLoadNumMap.get(resPath);
if (!Helper.isNullOrUndefined(num)) {
num--;
this.resLoadNumMap.set(resPath, Math.max(num, 0));
if (num <= 0) {
cc.loader.releaseRes(url);
this.resLoadNumMap.delete(resPath);
}
}
}
}
/**
* 从resources目录加载asset
* @param url
* @param assetType
*/
loadRes(url: string, assetType?: typeof cc.Asset): Promise<any> {
return new Promise(resolve => {
let res = cc.loader.getRes(url, assetType);
if (cc.isValid(res)) return resolve(res);
cc.loader.loadRes(url, assetType, (err, res) => {
if (err) {
cc.warn("loadAsset error", url);
resolve(err);
} else if (cc.isValid(res)) {
resolve(res);
} else
resolve(err);
});
});
}
}
/**
* 从resources目录加载prefab(省略资源后缀),加载成功后生成prefab实例
* @param url
*/
loadPrefabObj(url: string): Promise<cc.Node> {
return new Promise(resolve => {
let res: cc.Prefab = cc.loader.getRes(url, cc.Prefab);
if (cc.isValid(res))
return resolve(cc.instantiate(res) as cc.Node);
cc.loader.loadRes(url, cc.Prefab, (err, res: cc.Prefab) => {
if (err) {
resolve(null);
} else if (cc.isValid(res)) {
resolve(cc.instantiate(res) as cc.Node);
} else
resolve(null);
});
});
}
private static _instance = null;
static get I(): LoaderCenter {
return this._instance || (this._instance = new LoaderCenter);
}
}
export const LoaderMgr = LoaderCenter.I;


