Search Unity

Help with WWW.GetAudioClip Freeze please

Discussion in 'Scripting' started by edwood_grant, May 15, 2012.

  1. edwood_grant

    edwood_grant

    Joined:
    Jan 11, 2010
    Posts:
    29
    Hello,

    I've been loading some audio music clips from the web using WWW (and in some cases saving in the disk and then reloading again, due to some WWW limitations).

    Everything actually works fine, but the problem I have is that when I use the WWW.GetAudioClip function, or even WWW.audioClip, the game freezes for a while. This freeze is mild in the webplayer, but in mobile devices it can really be seen for about 2-3 seconds.

    I assume this happens because, well, it is a song of about 2-3 MB and it guess that it must load all of that into memory. But I would like to know if there is a way that I can async load this somehow so the freeze stops.

    I could set the streaming parameter to true, but the thing is that I need the sample data to interact with, so that is not possible. I can't use threads either, because almost all of the Unity API is not thread safe, and it won't let me use it on threads (throws an error when doing it).

    And I cannot use AssestBundles because A) I don't have Pro version, and B) I get the songs in mp3 or ogg format from an external service...

    I know there is no much room to work on, and I am starting to assume there is nothing I can do about it and ill have to let it be that way. But I still write this question to ask if anybody has fund a workaround or if anyone has another solution to this problem?

    Thanks a lot.
     
  2. kilt

    kilt

    Joined:
    Oct 12, 2011
    Posts:
    136
    Do you absolutely have to use WWW? can you use a resources folder instead? or is that not allowed in mobile devices?
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    you can not load from web through anything but WWW

    As for the freeze: thats to expect. When you access the audioclip, then the audioclip gets generated from the bytes and loaded and if you use compressed songs then that means decompression on load which is very cpu intense especially when you throw 3 minutes of audio at it. There is no way around this beside making your audio clips reasonably small or getting the pro licenses to use asset bundles to set them to 'stream from disk' out of the cache (www.loadfromcacheordownload)
     
  4. edwood_grant

    edwood_grant

    Joined:
    Jan 11, 2010
    Posts:
    29
    Oh well, I guess it can't be helped then.

    The thing is, even if I had pro version, I couldn't use AssetBundles because I am using an external service which I cannot control and only has files either in mp3 or ogg, I'll guess I'll just have to show a warning when the song is loading and let it freeze for a while (fortunately it is not such a big time).

    Anyhow, thanks a lot for taking your time to answer n_n.
     
  5. edwood_grant

    edwood_grant

    Joined:
    Jan 11, 2010
    Posts:
    29
    Hmm id o have an interesting and odd situation. In some cases ill use the OGG format for the music, and it so happens that when i used the deprecated function www.oggVorbis works with no hitches, but using the standard WWW.audioClip, there is a freeze... odd.

    Maybe inside the code that deprecated function has a way of actually asynchronously loading the music file? Oh well, either way is not something I could do anything about it. Nevertheless it is interesting, and at least a function that can save me the freeze in some case...
     
  6. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    Hi Edwood

    Please try using Unity 3.4. We have the same problem with version 3.5.
     
  7. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    What SOMEWHAT helps is telling unity what type of audio data to expect
    Code (csharp):
    1.  
    2.  www.GetAudioClip (true, true,  AudioType.OGGVOBIS); // this is sudo code, check the docs, I don't feel like opening up mono to exactly figure it out right now
    3.  
    4.  
    Also you can set it to start playing before its fully downloaded, for some reason this helps a bit, although then you cant seek in the audio clip
     
  8. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    Thanks Keith

    It works only for Ogg Vorbis when testing on the Unity Editor. I tried switching to iOS and using AudioType.MPEG but the clip does not even start to sound.

    Andres
     
  9. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    mpeg is only support on the device (anywhere else it requires license fees), while ogg vorbis is not supported on the device (is not hw accelerated which makes it a major performance killer. Thats the reason why movie textures don't work either, ogg theora would kill the whole 'realtime' experience)
     
  10. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    Hi Dreamora. You can download and play mp3's on the Unity editor if you switch the platform to iOS.

    But to make the definitive test, I built and run the iOS version without success using www.GetAudioClip (true, true, AudioType.MPEG);

    There is no error and no sound either.
     
  11. keithsoulasa

    keithsoulasa

    Joined:
    Feb 15, 2012
    Posts:
    2,126
    Hmm, I'm not runing IOS, but on android this is what works
    Code (csharp):
    1.  
    2.             Player.audio.clip = www.GetAudioClip(true,true,AudioType.MPEG);
    3.  
    If I had to guess Apple might be disabling this type of download due to security issues ?
    Although I really have no idea
     
  12. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    What happens is that the isReadyToPlay variable is never changed to true.
     
  13. r618

    r618

    Joined:
    Jan 19, 2009
    Posts:
    1,305
    you have to wait for the network ideally in the coroutine when playing streamed audio something like :

    Code (csharp):
    1.  
    2.   while (!this.audio.clip.isReadyToPlay ) {
    3.    Debug.Log("audio stream not ready yet");
    4.    yield return null;
    5.   }
    6.        
    7.   this.audio.Play();
    8.  
    it takes few frames, but the audio catches up eventually; if the format is supported
    ( btw this should be in the docs if i remember correctly )

    so 'isReadyToPlay' works fine for me, the 'isPlaying' property not quite so for steamed audio
     
  14. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    I know r618. That is what we use in our code to start playing a downloaded song. But it is not changing its value to true.

    We just did a test using www.progress and it shows that the full song is being downloaded. But when played there is no sound.
     
  15. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    If the Stream parameter is true, it does not play any sound.

    If the Stream parameter is false it plays the song but the framerate gets compromised for an instant while the song is decompressed.

    The www.threadPriority should work on Audio decompression not only on Assetbundles.

    Now we are looking on how to play the song on a separate thread.
     
  16. xulsc

    xulsc

    Joined:
    Oct 24, 2012
    Posts:
    2
    I've been having the same exact problem with some songs not playing, even after checking to make sure they fully load from the WWW constructor call. It happens to some consistent random songs, and I noticed similar behavior where the isReadyToPlay never becomes true.

    The workaround I used is to detect after the GetAudioClip call if the clips length is 0, then load the full song. Get the same issue with the harsh hiccup "Not Responding" style freeze as it loads. If anyone could help with a solution for the freeze, the load time could be less harsh as you can add a progress bar or some other sort of notification.
     
  17. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    Thanks xulsc

    How exactly do you do the full song loading?
     
  18. xulsc

    xulsc

    Joined:
    Oct 24, 2012
    Posts:
    2
    Set the stream parameter to false in the GetAudioClip call, I meant.
    So do the GetAudioClip call with stream set to true, if the length of the clip is 0 after that, do another GetAudioClip call with stream set to false. That way you completely load the audio clips from the files that you have to, resulting in a freeze only on those and then you have the ones that can stream that load instantly.

    This fixes the issue I was having where some files would get the clip and some wouldn't ever get the clip, even after ensuring the WWW file is completely loaded checking versus the properties isDone and progress. I reported this as a bug to Unity, as its completely random for what songs this happens to, even ones of the same AudioType.

    This does not solve the original problem where it freezes when you run the GetAudioClip without streaming though, unfortunately.
     
    Last edited: Oct 24, 2012
  19. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    Unfortunately this workaround does not solve our problems.

    We created two plugins, one for iOS and another one for Android to download and play songs without freezes.

    If there is enough interest we may consider releasing them in the asset store. Eventually Unity will solve these problems anyway.

    Andres
     
  20. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    This problem is solved if the MP3 is encoded with Constant Bit Rate.

    Thanks to Unity Support for the workaround solution.

    Andres
     
  21. exitsimulation

    exitsimulation

    Joined:
    Feb 10, 2014
    Posts:
    82
    Is this workaround still available?

    I have the same 'freezing' problem due to using non-streamed audio via GetAudioClip(false,false). I just tried the constant bit rate approach and it still had to load the file completely which froze the app as usual... Any ideas?
     
  22. fawnha

    fawnha

    Joined:
    Oct 27, 2012
    Posts:
    2
    Why don't they use another core to decompress the audio? It's insane that in this day and age they are only using a single core to do everything. Most devices have 2 to 4 cores. Why aren't they used?
     
  23. Freddy888

    Freddy888

    Joined:
    Sep 13, 2014
    Posts:
    165
    Same problem. I'm loading audio on the fly from the web. Every time I do the screen freezes. Has this been fixed or a solution been discovered please ?
     
  24. Christie Jacob

    Christie Jacob

    Joined:
    Apr 23, 2015
    Posts:
    1
    can u please help me here! how did u create those plugins(im working on android)? i'm having the same freeze problm! sir,can you please mail what i should do (christeejacobs@gmail.com)
     
  25. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    We no longer use plugins.

    The problem was solved by changing the MP3 encoding to Constant Bit Rate.
     
  26. Jakhongir

    Jakhongir

    Joined:
    May 12, 2015
    Posts:
    37
    @bakno you said that you created some plugins to play loaded via www mp3 without freezes. Could you give some info, do you sell it or can just share? www.GetAudioClip() and www.audioClip is still freezing in unity 5.2.1.
     
  27. bakno

    bakno

    Joined:
    Mar 18, 2007
    Posts:
    604
    @Jakhongir We no longer use plugins. The problem was solved by changing the MP3 encoding to Constant Bit Rate.