Jump to content

Questions about embedding sounds/music in your game


ForgeableSum
 Share

Recommended Posts

Two questions:

1. I want to stream my in-game music, since there are 15 tracks and it would take too long to download each. Obviously, I could use a service like soundcloud - but would I have to either show the embed widget or show a link to the sound cloud page every time the song played (as their "attribution" section in API terms seem to imply)?

https://developers.soundcloud.com/docs/api/terms-of-use#commercial

I've actually done a lot of research on this and haven't come up with anything. Googled "steam music to your app," "stream music to your web game," etc. Not a single result. I suppose it's because streaming is generally directly business to consumer, not business to business to consumer. I suppose it's a very rare thing to do as most web games simply download the sound files when you access the page. 

Does anyone have any advice/personal experience regarding this? What are my options? Just trying to gain some perspective as I can't find anything in my research. 

2. Suppose I have 100 sound files (these are effects, not music, so don't need to be streamed) in my game. Well, using individual sound files is bad for performance, especially when there are 100 of them and less than 500KB each... The client needs to make 100 HTTP requests to download the files instead of one.  It just makes sense to put them all in the same file and play sections of that single track (analogous to how we use texture atlases instead of separate texture files). For textures, we have texture packer. But what about for sounds? Is it even possible? 

 

 

Link to comment
Share on other sites

20 minutes ago, Zygomatic said:

1. I wouldn't stream. Just preload 1 track and during play preload the second track. Or if a user can choose, download the selected track and play it

2. Yes it is possible, it is called a sound sprite or an audio sprite. Tool: https://github.com/tonistiigi/audiosprite. I think supported by Phaser.

1. I think that would be unwise in my particular circumstance, because of the demands it puts on server bandwidth. I have 15 audio files, each are about 5MB. That's 75MB of bandwidth if the user goes through the entire soundtrack (to put things into perspective, the rest of the entirety of my game is 30MB, maybe)... I'd be much more comfortable if all of the stuff in my game that could be streamed, is streamed. Think I will send soundcloud an email today to figure this out. Other than soundcloud, I can't think of any service I could use for streaming. 

2. Makes sense. and it would seem Phaser does have support:

https://phaser.io/examples/v2/audio/audio-sprite

Link to comment
Share on other sites

22 hours ago, b10b said:

Consider that streaming audio requires a fair chunk of available cpu and power resources to decode.  A modular preloaded approach to extensive music might be an alternative plan?

Suppose I load each audio file on-demand, when the user needs them, using game.load.audio. If that file is in cache, game.load.audio will use the file from cache and not re-download, just like it works with images, correct?

it would be practical if I used really small MP3 files. But how does one dynamically load an audio file while a game is running? I'm not even sure how to do it outside of Phaser. 

 

Link to comment
Share on other sites

Audio files need to be downloaded and then decoded.  Decoding can be a significant CPU task (blocking) on mobile and is rarely something that is cacheable at the file level - so avoid this during active gameplay.  My advice (assuming this is for an RTS?) is have a preloader before each Level - load the assets needed for that Level only then, and don't worry about duplicate asset requests.  Use the preloading screen to display information about the upcoming battle so that the passive moment is still useful..  The device will then cache as best it can using its inbuilt methods and capabilities, resulting in most duplicate requests being ~instant.

Link to comment
Share on other sites

1 hour ago, feudalwars said:

But how does one dynamically load an audio file while a game is running?

Hi, I had to do this in one of our games. Reason was, that there was bug in Chrome in past, when decoding of audio files took ages. So, we loaded only initial menu music in preloader state and the in create() method we started loading of other music tracks for levels:

            // start loading in game music
            var musicLoader = new MusicManager(this.game);
            musicLoader.loadMusic();

Music Manager class looked like this - it creates its own instance of Phaser.Loader:

module Shards {

    export class MusicManager {

        private _game: Phaser.Game;
        private _loader: Phaser.Loader;

        private _musicToPlay: number;

        // -------------------------------------------------------------------------
        public constructor(game: Phaser.Game) {
            this._game = game;
            this._loader = new Phaser.Loader(game);

            this._musicToPlay = -1;
        }

        // -------------------------------------------------------------------------
        public loadMusic(): void {
            // load music
            var path = "assets/";
            for (var i = 0; i < Global.MAX_MUSIC; i++) {
                var music = "Music" + i;
                console.log("loading music ..." + music);

                /* if (this.game.device.ie && this.game.device.ieVersion <= 10) {
                    this._loader.audio(music, [path + music + ".mp3"]);
                } else */ {
                    this._loader.audio(music, [path + music + ".ogg", path + music + ".m4a"]);
                }
            }

            this._loader.onFileComplete.add(this.onFileComplete, this);
            this._loader.start();
        }

        // -------------------------------------------------------------------------
        public onFileComplete(progress: number, cacheKey: string, success: boolean, totalLoaded: number, totalFiles: number): void {
            //console.log("file loaded " + cacheKey + " adding to audio");

            var music = this._game.add.audio(cacheKey);
            Utils.AudioUtils.addMusic(cacheKey, music);
        }

        // -------------------------------------------------------------------------
        public getMusic(): string {
            var index = this._musicToPlay;
            if (index === -1) {
                index = this._game.rnd.integerInRange(0, Global.MAX_MUSIC - 1);
                this._musicToPlay = index;
            }

            do {
                var musicName = "Music" + index;
                console.log("request to play music ..." + musicName);

                if (this._game.cache.getSound(musicName) && this._game.cache.isSoundDecoded(musicName)) {
                    // index for next music
                    this._musicToPlay = (index + 1) % Global.MAX_MUSIC;
                    console.log("returning music " + musicName);
                    return musicName;
                }

                index = (index + 1) % Global.MAX_MUSIC;
            } while (index !== this._musicToPlay);

            return null;
        }
    }
}

 It loads music files while game is already running. getMusic() method is trying to play them one after another. But it also checks if next music is already ready (loaded and decoded). If not, it returns next, that is already prepared.

 Word of warning - if your music files have 75MB, it will have much more after decoding - it is the same as decoding .jpg into texture.

 For audiosprites: I also use tool mentioned by @Zygomatic and I am using export from it directly in game. One problem is, that IE cannot play one sound multiple times (even if you set allowMultiple to true) - as I found, it relates to whole audiosprite file, so playing "soundA" interrupts playing "soundB". In the end, I had to make separate assets for IE and others. Assets for IE are per file, while aseets for others are audiosprites (both .ogg and .mp4). Correct assets are loaded in preloader. While for IE I do not use audiosprite, I still use export from audiosprites tool to at least read sound names from it (so I do not have to mange any extra list in code).

 

EDIT: one more thing - I think, that music using audio tag (not WebAudio) can be easily streamed. Others may know more about it. Look here: http://stackoverflow.com/questions/24221591/streaming-mp3-instead-of-downloading-it-with-html5-audio-tag

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...