cocos2d / cocos2d-x

Cocos2d-x is a suite of open-source, cross-platform, game-development tools utilized by millions of developers across the globe. Its core has evolved to serve as the foundation for Cocos Creator 1.x & 2.x.
https://www.cocos.com/en/cocos2d-x
18.28k stars 7.05k forks source link

AudioEngine::preload should support to pass a url vector as parameter #16085

Open dumganhar opened 8 years ago

dumganhar commented 8 years ago

Now we only support:

void AudioEngine::preload(const std::string& filePath, std::function<void(bool isSuccess)> callback)

If there're lots of effect files need to be preloaded, developer has to invoke preload function many times, and must pay more attention to callback function.

Probably, a new interface like:

void AudioEngine::preload(const std::vector<std::string>& filePaths, const std::function<void(const std::string& url, bool isSucceed)>& callback); 

Any thoughts?

@minggo

minggo commented 8 years ago

Sounds good.

alfogrillo commented 8 years ago

@dumganhar I think would be very useful also to preload all files from a folder (recursively or not).

Something like that: void AudioEngine::preload(const std::string& folderPath, std::function<void(bool isSuccess)> callback, bool recursive = false);

liuyi commented 8 years ago

I think the best way is that creating a audioManager according to your needs. For example, here is a API in my custom audioManager (JSB)

/* * @desc 在游戏中不要直接使用此接口播放声音 而是根据功能选择使用playVoiceByTag,playEffectSound,playBgSound .停止某一个声音,则根据播放返回的INDEX 操作 * @param path * @param loopOrTimes {boolean| number} * @param volume 0-1; * @param opts {object<sole.,restart.,onended.,tweenVolume.>} * sole:如果为真,则这个声音同时只能播放一个,restart * 如果设置为真,则在sole为真的情况下 * 当前声音从头播放, onended 当声音播放完毕会执行的动作,为简化操作,不支持多个回调.一个声音只支持一个回调. tweenVolume 如果为真则,对声音做淡入处理 * @returns {|int} */ AudioManager.prototype.playSound = function (path, loopOrTimes, volume, opts) {

};

A base audio class don't need too much extra function, because is not everyone has the same requirements as you.

Thanks.

minggo commented 8 years ago

@liuyi if i understand correctly, you disagreed @Drakon-Cocos 's requirement, not this issue. Right? If so, i agree with you.

liuyi commented 8 years ago

@minggo Yes, I have different opinion。 Just keep it simple!

alfogrillo commented 8 years ago

@liuyi I think that folder preloading is simple as concept. Today I didn't found a multi platform way to list files inside a folder. Therefore each time I add a sound or an image to the project I have to code the associated URL for preloading. This is time consuming and errore prone. Anyway it is just my opinion.

liuyi commented 8 years ago

@Drakon-Cocos
Preload lots of sounds maybe need a lot of memory, especially in some low devices(such as smart TV)

1、Put whole sounds to a folder in res folder. 2、Create “resource.js” automatically,add all the sounds to the resource.js. You can write a tool by node.js or python etc. 3、 Write a wrapper function to preload these sounds in "resource.js".

resource.js example:

"voice": { "zh": { "home": { "addVip": "res/voice/zh/home/addVip.mp3", "click_buy_level_1_1": "res/voice/zh/home/click_buy_level_1_1.mp3", "download_error": "res/voice/zh/home/download_error.mp3",

        },
        "splash": {
            "didi_luanch_01": "res/voice/zh/splash/didi_luanch_01.mp3",
            "didi_luanch_02": "res/voice/zh/splash/didi_luanch_02.mp3"
        },
        "system": {
            "auto_login_failed": "res/voice/zh/system/auto_login_failed.mp3",
            "guest_welcome": "res/voice/zh/system/guest_welcome.mp3",
            "login_success": "res/voice/zh/system/login_success.mp3"
        }
    }

I think this way is faster than scanning folder.

Here is a nodeJS code snippets, I use it generate resource list:

` appKit.generateRes = function (dir, obj, parentDir, exucludes) {

exucludes = exucludes || [];
var state = fs.statSync(dir);

if (state.isDirectory() == false) {
    console.log("Input a directory please.");
    return;
}
//get all scripts in this folder.
var files = fs.readdirSync(dir);
// console.log(files);
var len = files.length;
var parentDir = (parentDir == null || parentDir == "") ? dir : parentDir + "/" + dir;
var childDir, file;

var needDeleteKeys = [];
for (var i = 0; i < len; i++) {
    file = files[i];
    childDir = (parentDir != null && parentDir != "") ? parentDir + "/" + files[i] : files[i];

    var state = fs.statSync(childDir);
    if (state.isDirectory()) {
        var childObj = obj[file] = {};
        appKit.generalRes(childDir, childObj, null, exucludes);
    } else {
        if (exucludes.indexOf(file) < 0) {
            /// var fileName=file.
            //console.log(typeof(file));
            var fileName = file.substring(0, file.lastIndexOf("."));
            if (obj[fileName] == null) {
                obj[fileName] = childDir;
            } else {
                //给重复的文件重新命名键名。
                var old_fileSrc = obj[fileName];
                //console.log("=====>>>>"+fileName)
                // console.log(old_fileSrc)
                //console.log("XX")
                if (typeof(old_fileSrc) == "object") {
                    //this is a folder,change the name of new file.
                    var currentFileName = file.replace(/\./g, "_");
                    obj[currentFileName] = childDir;
                } else {
                    var old_fileName = old_fileSrc.substring(old_fileSrc.lastIndexOf("/") + 1);
                    var new_fileName = old_fileName.replace(/\./g, "_");
                    obj[new_fileName] = old_fileSrc;

                    needDeleteKeys.push(fileName);

                    var currentFileName = file.replace(/\./g, "_");
                    obj[currentFileName] = childDir;
                }

            }

        }
    }
}//end for

for (var k = 0; k < needDeleteKeys.length; k++) {
    delete obj[needDeleteKeys[k]];
}

};`

Shulepov commented 8 years ago

Agree with @liuyi, i think it better to keep AudioManager simple. Adding multiple files can be done inside for-loop.

Preloading sounds from directories have one big disadvantage - obtaining files list may be very slow on some platforms (e.g. on Android).