Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
dumganhar opened this issue Jul 11, 2016 · 8 comments
Open
Assignees

Comments

@dumganhar
Copy link

dumganhar commented Jul 11, 2016

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

@dumganhar dumganhar self-assigned this Jul 11, 2016
@minggo
Copy link
Contributor

minggo commented Jul 11, 2016

Sounds good.

@dumganhar dumganhar changed the title AudioEngine::preload should support to passing a url vector AudioEngine::preload should support to pass a url vector as parameter Jul 11, 2016
@alfogrillo
Copy link
Contributor

@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
Copy link

liuyi commented Jul 15, 2016

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
Copy link
Contributor

minggo commented Jul 15, 2016

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

@liuyi
Copy link

liuyi commented Jul 15, 2016

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

@alfogrillo
Copy link
Contributor

@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
Copy link

liuyi commented Jul 15, 2016

@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
Copy link
Contributor

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).

@dumganhar dumganhar added this to the next milestone Feb 15, 2017
@dumganhar dumganhar modified the milestones: 3.16, next Sep 20, 2017
@drelaptop drelaptop modified the milestones: 3.17, 3.18 May 21, 2018
@drelaptop drelaptop modified the milestones: 3.17.1, next Nov 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants