Search Unity

  1. We've closed the job boards. If you're looking for work, or looking to hire check out Unity Connect. You can see more information here.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. If you're a macOS 10.13 High Sierra user take be sure to read this before updating Unity.
    Dismiss Notice
  5. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  7. Unity 2017.3 beta is now available for download.
    Dismiss Notice

WWW.audioClip followed by audiosource.play() fails, except when breaking with debugger

Discussion in 'Audio & Video' started by manutoo, Jul 20, 2015.

  1. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    233
    Hello,

    I'm trying to add to possibility for my users to add their own sounds to my game.
    To do so, I'm loading the audio file like this :
    Code (CSharp):
    1.         WWW Loader = new WWW("file:///" + LoadName);
    2.          AudioClip Clip = Loader.audioClip;
    3.  
    4.          if (Clip.loadState != AudioDataLoadState.Failed)
    5.          {
    6.            int Counter = 0;
    7.  
    8.            Debug.Log(string.Format("Clip State = {0}!", Clip.loadState));
    9.  
    10.            while (Clip.loadState == AudioDataLoadState.Loading && Counter < 50)
    11.            {
    12.              System.Threading.Thread.Sleep(1);
    13.              ++Counter;
    14.            }
    15.  
    16.            Clip.name = LoadName;
    17.            return Clip;
    18.          }
    And then I bind the returned clip to an AudioSource and call Play().
    If I run the game normally, no sound is produced. Even if I do several Play() calls.
    Output is "Clip State = Unloaded!".

    But if I use the debugger and break on "while (Clip.loadState == AudioDataLoadState.Loading && Counter < 50)" and run again, then I hear a sound when AudioSource.Play() and its subsequent calls.
    In the Debugger Loader.audioClip.loadState is at AudioDataLoadState.Loaded .
    And output is "Clip State = Loaded!".

    I cannot easily Yield one frame here, as it'd break all the flow of my sound handling.

    Is it a bug that I should report ? Is it normal ? Is there any way to bypass that issue ?

    Thanks in advance for any help !
     
  2. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    233
    I added :
    Code (CSharp):
    1. if (Channel.m_AudioSource.clip.loadState == AudioDataLoadState.Loaded)
    before to call Play(), and now it still doesn't work on 1st time (ie: Play() isn't called), but subsequent calls work !

    Actually, I can easily delay by 1 frame the Play() (unlike the Loading part), so I'm going to do that... :)
     
  3. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    149
    I've come across a similar issue and it appeared to be a bug with Unity's www class (race condition?). If you call audioClip.isReadyToPlay it seems to "fix" it.

    Try to do this at any point before playing.

    Code (csharp):
    1.  
    2. bool fix = audioClip.isReadyToPlay;
    3.  
     
  4. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    233
    @HelloMeow,
    I tried that, it doesn't seem to change anything, plus isReadyToPlay is now deprecated.
    "if (Clip.loadState != AudioDataLoadState.Failed)" should be equivalent to it.
     
  5. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    I'm having the same issue or a similar issues with a music player script that had been working fine for the past couple of years... seems unity updated something and now it's hit and miss, sometimes it works and sometimes it does not. When it does not work the Unity console throws a weird red error but with no description of what that error is, however if I double click it takes me to this part of our code.
    while(!clip.isReadyToPlay)

    Code (CSharp):
    1. IEnumerator LoadFileAndPlay(string path)
    2.     {
    3.         WWW www = new WWW("file://" + path);
    4.         print("loading " + path);
    5.         AudioClip clip = www.GetAudioClip(false);
    6.         amLoading = true;
    7.         while(!clip.isReadyToPlay)
    8.             yield return www;
    9.         amLoading = false;
    10.      
    11.         print("done loading");
    12.         clip.name = Path.GetFileName(path);
    13.         source.Stop();
    14.         if(musicFile!=null)
    15.             Destroy(musicFile);
    16.         musicFile = clip;
    17.         PlayCurrent();//Note: source.clip is set in PlayCurrent so we don't do it here
    18.  
    19.         Debug.Log (clip);
    20.         StartCoroutine (LoadedfMessage());
    21.     }
    If I hover over it I get some message about obsolete or depreciated value... does anyone know how to fix this?
    I REALLY wish they would stop messing with the code especially on stuff that worked fine before... makes development on a long project all that much more difficult having to go back and fix stuff that I really shouldn't have too fix!!
     
  6. r618

    r618

    Joined:
    Jan 19, 2009
    Posts:
    431
    replace your line 4. with this:
    Code (CSharp):
    1. yield return www;
    functionality gets deprecated _all the time_ - you have to adapt; in case the above does not work, use the new webrequest
     
  7. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    Line 4 is just a print to console??
     
  8. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    233
    @zentaiguy,

    try to replace your lines #7 & 8 with :

    Code (CSharp):
    1.             while (!wwwLoader.isDone)
    2.                 yield return null;
    3.            
     
  9. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    I tried that and I got the following error:
    Severity Code Description Project File Line Suppression State
    Error CS0103 The name 'wwwLoader' does not exist in the current context kittsoftware C:\Users\mdkgr\Desktop\kittsoftware\Assets\Scripts\OSCoreScripts\Misc\TestScripts\AltMusicPlayer.cs 245 Active
     
  10. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    233
    oops, forgot to edit that from my code, in yours it's "www", not "wwwLoader", so it's "while (!www.isDone)".
     
  11. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    lol np, I'm just very pleased you are able to help
    OK so I think that fixed part of the problem.... now it's doing something weird:
    although there are other songs in the folder it just seems to only want to play two of the songs.??

    So I'm wondering if perhaps the way the songs are named might have anything to do with that as the two it only wants to play have no spaces in their titles example:

    KnightRider & KnightRiderNarataed

    VS

    Kenny Loggins - Danger Zone
     
  12. manutoo

    manutoo

    Joined:
    Jul 13, 2010
    Posts:
    233
    It's possible.
    I use "new WWW("file:///" +" instead of "new WWW("file://" +" ; check if it helps. Else, try to remove spaces to be sure it comes from that.
     
  13. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    I put that extra slash in there and it still does the same thing.
    I also get that weird red error in the console with no description however if i double click it, it takes me to this part of my code:
    AudioClip clip = www.GetAudioClip(false);
     
  14. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    Seems like no matter what I try it only want to play those two songs. In the inspector I can see it flashing though all the other songs in the folder but it just settles only on either of those two songs.... this is beyond stupid!!
     
  15. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    Can anyone see why this is no longer working properly??

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.IO;
    5. using System.Linq;
    6. using UnityEngine.UI;
    7.  
    8. public class AltMusicPlayer : MonoBehaviour
    9. {
    10.  
    11.     // Reference to KITT Modes Object
    12.     public KITTmodes KITTmodesObject;
    13.     // Reference To The IVR Button Manager Object
    14.     public IVRButtonManager IVR_BTNmgr;
    15.  
    16.     public Text MusicListText;// Reference to my UI Display Text for Songs
    17.     //public Text MusicListText2;
    18.     private string display = "";//UI Text reference
    19.     public enum SeekDirection { Forward, Backward }
    20.    
    21.     public AudioSource source;
    22.     bool shuffle;
    23.     bool isMute;
    24.     float volume;
    25.  
    26.     bool playing = true;
    27.     bool amLoading;
    28.     public AudioClip musicFile;
    29.    
    30.     [SerializeField] [HideInInspector] private int currentIndex = 0;
    31.    
    32.     private FileInfo[] soundFiles;
    33.     private List<string> validExtensions = new List<string> { ".ogg", ".wav" }; // Don't forget the "." i.e. "ogg" won't work - cause Path.GetExtension(filePath) will return .ext, not just ext.
    34.     private string absoluteMusicPath = "./Audio/Music";     // relative path to where the app is running - change this to "./music" in your case
    35.     private string absolute60sPath = "./Audio/Music/60s"; // relative path to where the app is running - change this to "./music/60s" in your case
    36.     private string absolute70sPath = "./Audio/Music/70s"; // relative path to where the app is running - change this to "./music/70s" in your case
    37.     private string absolute80sPath = "./Audio/Music/80s"; // relative path to where the app is running - change this to "./music/80s" in your case
    38.     private string absolute90sPath = "./Audio/Music/90s"; // relative path to where the app is running - change this to "./music/90s" in your case
    39.     private string absoluteFavoritesPath = "./Audio/Music/Favorites"; // relative path to where the app is running - change this to "./music/Favorites" in your case
    40.    
    41.  
    42.     void OnEnable(){
    43.         StartCoroutine (MessageCentreLoadingMessage());
    44.     }
    45.  
    46.     void Start()
    47.     {
    48.        
    49.         PlayerPrefs.GetFloat ("music");
    50.         //being able to test in unity
    51.         if (Application.isEditor)
    52.             absoluteMusicPath = "Assets/Audio/Music";
    53.             absolute60sPath = "Assets/Audio/Music/60s";
    54.             absolute70sPath = "Assets/Audio/Music/70s";
    55.             absolute80sPath = "Assets/Audio/Music/80s";
    56.             absolute90sPath = "Assets/Audio/Music/90s";
    57.             absoluteFavoritesPath = "Assets/Audio/Music/Favorites";
    58.        
    59.         if (source == null)
    60.             source = gameObject.AddComponent<AudioSource> ();
    61.         ReloadSounds ();
    62.     }
    63.    
    64.  
    65.     void Update(){
    66.         if (!source.isPlaying && playing && !amLoading)
    67.         {
    68.             //StartCoroutine(LoadFileAndPlay(soundFiles[currentIndex].FullName));
    69.             if (shuffle) {
    70.                 currentIndex = Random.Range (0, soundFiles.Length);
    71.             }
    72.                 else {
    73.                     Seek(SeekDirection.Forward);
    74.                     //StartCoroutine(LoadFileAndPlay(soundFiles[currentIndex].FullName));
    75.                 }
    76.             StartCoroutine(LoadFileAndPlay(soundFiles[currentIndex].FullName));
    77.         }
    78.     }
    79.  
    80.     public void MuteMusic() {
    81.         isMute = ! isMute;
    82.         DataHolder DH = FindObjectOfType<DataHolder> ();
    83.         DH.musicMuteOnOff();
    84.         source.volume =  isMute ? 0 : 1;
    85.         if (isMute) {
    86.             MessageCentreManager MmM = FindObjectOfType<MessageCentreManager> ();
    87.             MmM.GoMusicPlayerMuteMessage ();
    88.             PlayerPrefs.SetFloat ("music", 0);
    89.             IVR_BTNmgr.KITT_IsPlayingAudioRecording = false;
    90.  
    91.         }
    92.         if (!isMute) {
    93.             MessageCentreManager MuM = FindObjectOfType<MessageCentreManager> ();
    94.             MuM.GoMusicPlayerUnmuteMessage ();
    95.             PlayerPrefs.SetFloat ("music", 1);
    96.             IVR_BTNmgr.KITT_IsPlayingAudioRecording = true;
    97.         }
    98.     }
    99.    
    100.    
    101.     //My New UI Buttons Added
    102.     public void PlayPrevious (){
    103.         if (KITTmodesObject.KITT_SaboMP == true) {
    104.             // Do Nothing
    105.         } else {
    106.             Seek (SeekDirection.Backward);
    107.             StartCoroutine (LoadFileAndPlay (soundFiles [currentIndex].FullName));
    108.         }
    109.     }
    110.  
    111.     public void PlayCurrentClip () {
    112.         if (KITTmodesObject.KITT_SaboMP == true) {
    113.             // Do Nothing
    114.         } else {
    115.             StartCoroutine (LoadFileAndPlay (soundFiles [currentIndex].FullName));
    116.             playing = true;
    117.         }
    118.     }
    119.  
    120.     public void PlayNext () {
    121.         if (KITTmodesObject.KITT_SaboMP == true) {
    122.             // Do Nothing
    123.         } else {
    124.             Seek (SeekDirection.Forward);
    125.             StartCoroutine (LoadFileAndPlay (soundFiles [currentIndex].FullName));
    126.         }
    127.     }
    128.  
    129.     public void ReloadAudio () {
    130.         ReloadSounds();
    131.     }
    132.  
    133.     public void StopAudio () {
    134.         source.Stop ();
    135.         playing = false;
    136.         IVR_BTNmgr.KITT_IsPlayingAudioRecording = false;
    137.     }
    138.  
    139.     public void PauseAudio () {
    140.         source.Pause ();
    141.         playing = false;
    142.         IVR_BTNmgr.KITT_IsPlayingAudioRecording = false;
    143.     }
    144.  
    145.     public void ShuffleToggle()
    146.     {
    147.         shuffle = !shuffle;
    148.         DataHolder DH = FindObjectOfType<DataHolder> ();
    149.         DH.musicShuffleOnOff();
    150.     }
    151.  
    152.  
    153.     //End My New UI Buttons Added
    154.    
    155.     void Seek(SeekDirection d)
    156.     {
    157.         if (d == SeekDirection.Forward)
    158.             currentIndex = (currentIndex + 1) % soundFiles.Length;
    159.         else {
    160.             currentIndex--;
    161.             if (currentIndex < 0) currentIndex = soundFiles.Length -1;
    162.         }
    163.     }
    164.    
    165.     void PlayCurrent()
    166.     {
    167.         source.clip = musicFile;
    168.         source.Play();
    169.         Debug.Log (source.clip);
    170.         MusicListText.text = musicFile.name;
    171.         //MusicListText2.text = musicFile.name;
    172.         IVR_BTNmgr.KITT_IsPlayingAudioRecording = true;
    173.     }
    174.    
    175.  
    176.     void ReloadSounds()
    177.     {
    178.         // Load Music
    179.         if (KITTmodesObject.myMusicPlayerSetting == KITTmodes.MusicPlayerSetting.playmusic)
    180.         {
    181.             // get all valid files
    182.             var info = new DirectoryInfo(absoluteMusicPath);
    183.             soundFiles = info.GetFiles()
    184.                 .Where(f => IsValidFileType(f.Name))
    185.                 .ToArray();
    186.         }
    187.  
    188.         // Load 60s Songs
    189.         if (KITTmodesObject.myMusicPlayerSetting == KITTmodes.MusicPlayerSetting.play60s) {
    190.             // get all valid files
    191.             var info = new DirectoryInfo (absolute60sPath);
    192.             soundFiles = info.GetFiles ()
    193.                 .Where (f => IsValidFileType (f.Name))
    194.                 .ToArray ();
    195.         }
    196.  
    197.         // Load 70s Songs
    198.         if (KITTmodesObject.myMusicPlayerSetting == KITTmodes.MusicPlayerSetting.play70s) {
    199.             // get all valid files
    200.             var info = new DirectoryInfo (absolute70sPath);
    201.             soundFiles = info.GetFiles ()
    202.                 .Where (f => IsValidFileType (f.Name))
    203.                 .ToArray ();
    204.         }
    205.  
    206.         // Load 80s Songs
    207.         if (KITTmodesObject.myMusicPlayerSetting == KITTmodes.MusicPlayerSetting.play80s) {
    208.             // get all valid files
    209.             var info = new DirectoryInfo (absolute80sPath);
    210.             soundFiles = info.GetFiles ()
    211.             .Where (f => IsValidFileType (f.Name))
    212.                 .ToArray ();
    213.         }
    214.  
    215.         // Load 90s Songs
    216.         if (KITTmodesObject.myMusicPlayerSetting == KITTmodes.MusicPlayerSetting.play90s) {
    217.             // get all valid files
    218.             var info = new DirectoryInfo (absolute90sPath);
    219.             soundFiles = info.GetFiles ()
    220.                 .Where (f => IsValidFileType (f.Name))
    221.                 .ToArray ();
    222.         }
    223.  
    224.         // Load Favorites Songs
    225.         if (KITTmodesObject.myMusicPlayerSetting == KITTmodes.MusicPlayerSetting.playFavorites) {
    226.             // get all valid files
    227.             var info = new DirectoryInfo (absoluteFavoritesPath);
    228.             soundFiles = info.GetFiles ()
    229.                 .Where (f => IsValidFileType (f.Name))
    230.                 .ToArray ();
    231.         }
    232.     }
    233.    
    234.     bool IsValidFileType(string fileName)
    235.     {
    236.         return validExtensions.Contains(Path.GetExtension(fileName));
    237.     }
    238.    
    239.     IEnumerator LoadFileAndPlay(string path)
    240.     {
    241.         WWW www = new WWW("file://" + path);
    242.         print("loading " + path);
    243.         AudioClip clip = www.GetAudioClip(false);
    244.         amLoading = true;
    245.         //while(!clip.isReadyToPlay)
    246.         while (!www.isDone)
    247.             //yield return www;
    248.            yield return null;
    249.         amLoading = false;
    250.        
    251.         print("done loading");
    252.         clip.name = Path.GetFileName(path);
    253.         source.Stop();
    254.         if(musicFile!=null)
    255.             Destroy(musicFile);
    256.         musicFile = clip;
    257.         PlayCurrent();//Note: source.clip is set in PlayCurrent so we don't do it here
    258.  
    259.         Debug.Log (clip);
    260.         StartCoroutine (LoadedfMessage());
    261.     }
    262.        
    263.     void AddText()
    264.     {
    265.         display = currentIndex + " : " + musicFile.name;
    266.         MusicListText.text = display;
    267.         //MusicListText2.text = display;
    268.     }
    269.  
    270.     IEnumerator MessageCentreLoadingMessage(){
    271.         yield return new WaitForSeconds (1.5f); // wait time
    272.         MessageCentreManager4 MCLM = FindObjectOfType<MessageCentreManager4>();
    273.         MCLM.GoLoadingMessage ();
    274.     }
    275.  
    276.  
    277.     IEnumerator LoadedfMessage(){
    278.         yield return new WaitForSeconds (1.5f); // wait time
    279.         MessageCentreManager4 BM2 = FindObjectOfType<MessageCentreManager4>();
    280.         BM2.GoLoaddedMessage ();
    281.     }
    282.  
    283. }
    284.  
     
  16. NA-RA-KU

    NA-RA-KU

    Joined:
    May 5, 2013
    Posts:
    879
    Last edited: Dec 6, 2017
  17. zentaiguy

    zentaiguy

    Joined:
    Nov 23, 2014
    Posts:
    404
    Thanks, I'll have to look into that... I just find it super annoying to have to go back and change a whole bunch of stuff that was working fine just because they can't leave the code alone or at least have the decency to support the older code as well... makes the length of this bloody project all that much more longer and needlessly more difficult :(
    Plus I'm not really sure what to change in my existing code....