Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Open Source] AudioImporter

Discussion in 'Assets and Asset Store' started by HelloMeow, Sep 15, 2014.

  1. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280

    Asset Store | Github

    Here is a free package that lets you import mp3 files at runtime.

    AudioImporter enables you to import audio files at runtime in Unity. It loads an audio file into an AudioClip. The package includes a simple file browser that can be used to select a file.

    An optional importer using BASS dll and BASS net is included as a separate package. This importer needs additional licenses and steps to use. See Using Bass Importer for more information.

    Features:
    • Asynchronous importing
    • File browser
    • Supports Windows, Android and iOS
     
    Last edited: May 20, 2019
  2. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    A small update. This now includes an importer that uses Bass.dll and the importers are now derived from MonoBehaviour.
     
    Roxydoce likes this.
  3. RickyTB

    RickyTB

    Joined:
    Dec 13, 2014
    Posts:
    3
    Wow thankyou very much, this is going to help me a lot in a future project. Can't believe nobody has given you a thanks in all this time.
     
    Roxydoce likes this.
  4. F0RG0TTEN

    F0RG0TTEN

    Joined:
    Sep 20, 2015
    Posts:
    1
    Thank you for sharing this for free! I don't understand why didn't you get more attention for such useful tool like that one.
     
    Roxydoce likes this.
  5. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
  6. Ocram1989

    Ocram1989

    Joined:
    Jul 15, 2016
    Posts:
    1
    Is free this??
     
  7. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Yes. One of the importers uses Bass.dll, which is not free for commercial projects, but every importer is optional.
     
  8. ikemen_blueD

    ikemen_blueD

    Joined:
    Jan 19, 2013
    Posts:
    341
    @HelloMeow this is supppperrr useful, so many thanks. I emailed u before, can't wait for new update from RhythmTool, no memory allocations every frame plz :)
     
    Last edited: Jan 8, 2017
  9. jalemanyf

    jalemanyf

    Joined:
    Jun 16, 2013
    Posts:
    25
    Hello,

    It seems very interesting but I still can't do it Works...

    I'm using Unity 5.3.3f1 on a Windows 8.1 to test it.

    I have also downloaded the rythmtool sample: it opens, navigate for the folders but nothing sounds after select an mp3...

    Any idea about what I'm doing wrong?

    It seems easy to follow when I read but anyone has any step by step guide to be sure I have done everything correct?

    Thanks!
     
  10. Allthebees

    Allthebees

    Joined:
    Apr 22, 2017
    Posts:
    17
    Hey there. So I've been working on a game using your rhythm tool as well as these .mp3 importer.

    I was coming up against an issue where some mp3 files would not be able to load. After a bit of messing around, I found that the while loop in FillBuffer() in the DecoderImporter class would get stuck.

    Read would return 0, and therefore index would not increase. I am not 100% sure why the issue happens but a simple solution is to check if index + read is equal to index, and break out of the while loop if the condition is met.

    Hopefully this can help anyone else that might be running into this issue
     
  11. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Thanks for reporting this issue, I'm going to look into it.
     
  12. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Version 3.0 is ready. I've decided to put it up on the Asset Store and Github to make it easier to add to a project. It should be available on the asset store soon.
     
  13. trinusvr

    trinusvr

    Joined:
    Aug 16, 2015
    Posts:
    14
    Hi, I'm using the importer (and rhythm tool) to play audio clips from local storage (Android).
    It loads and plays the first song fine, but the Loaded event is not triggered a second time.

    loadSong (){
    importer.Loaded += songLoaded;
    importer.Import(getSelectedSong());
    }

    the second run gives this error:
    07-09 14:01:25.680 7832 7846 E Unity : ArgumentNullException: Value cannot be null.
    07-09 14:01:25.680 7832 7846 E Unity : Parameter name: _unity_self
    07-09 14:01:25.680 7832 7846 E Unity : at (wrapper managed-to-native) UnityEngine.Networking.UnityWebRequest.Abort(UnityEngine.Networking.UnityWebRequest)
    07-09 14:01:25.680 7832 7846 E Unity : at MobileImporter.Abort () [0x00008] in <f18bee95f8ef45a2b020e0963ca841ed>:0
    07-09 14:01:25.680 7832 7846 E Unity : at AudioImporter.Import (System.String uri) [0x00000] in <f18bee95f8ef45a2b020e0963ca841ed>:0
    07-09 14:01:25.680 7832 7846 E Unity : at SpawnScript.loadSong () [0x00047] in <f18bee95f8ef45a2b020e0963ca841ed>:0

    My current workaround is to comment out the Abort() call in Import(string uri) (AudioImporter.cs:50)
    This solves the issue, but I wonder if I'm doing something wrong... or it is a bug
     
  14. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    I think I might have fixed this last month, but I haven't updated the Asset Store package yet. Try this version on github:
    https://github.com/Hello-Meow/Audio...ssets/AudioImporter/Scripts/MobileImporter.cs

    By the way, in loadSong() you appear to subscribe to the AudioImporter.Loaded event every time. You'd only want to subscribe to this once. In Awake for example. Otherwise it will invoke songLoaded() an increasing number of times, every time you use loadSong().
     
  15. trinusvr

    trinusvr

    Joined:
    Aug 16, 2015
    Posts:
    14
    Thanks, will check the update.

    I was doing tests with the event subscription (deregistering in songLoaded(), or one time register at Start()), as I first thought the problem was related to the event handling (on second trigger). But thanks for commenting the potential issue :)
     
  16. TwighlightSparkle

    TwighlightSparkle

    Joined:
    Mar 4, 2016
    Posts:
    5
    Hello, excuse me, i want to use your asset in my work. But i have some troubles. On the first screenshot you can see the path to file i want to read (it is mp3 file).
    On the second screenshot there is code.
    On the third screenshot there is file i want to read. (Расположение = Path)
    Could you help me out? bandicam 2019-07-16 16-00-53-203.jpg bandicam 2019-07-16 16-02-28-268.jpg bandicam 2019-07-16 16-05-36-258.jpg
     
  17. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Hi,

    AudioImporter is a component. You can't instantiate a new component like that. You have to use AddComponent or GetComponent.

    That while loop will probably freeze the game. Progress will never reach 1 in the same frame unless there is an error opening the file.

    Please see the included example.
     
  18. TwighlightSparkle

    TwighlightSparkle

    Joined:
    Mar 4, 2016
    Posts:
    5
    Thank you for quick response.

    I do all like in example. But there is no changes.
    I try perform that script with AudioImporter and with NAudioImporter to. Anyway it writes: "is null". bandicam 2019-07-17 13-18-48-155.jpg
    bandicam 2019-07-17 13-18-24-063.jpg bandicam 2019-07-17 13-18-01-608.jpg
    bandicam 2019-07-17 13-46-52-899.jpg
     
  19. getschwiftyltd

    getschwiftyltd

    Joined:
    Aug 17, 2019
    Posts:
    6
    Hi, very clean interface for the importer. However, using mobile importer my whole game freezes on android (for about 1-2 seconds) while the import is happening. My code is straight from the example - with Coroutine and all that. Any advice? Thanks
     
  20. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    I've noticed this as well and it appears to be caused by
    DownloadHandlerAudioClip.GetContent. It's a bug according to this thread.
     
  21. getschwiftyltd

    getschwiftyltd

    Joined:
    Aug 17, 2019
    Posts:
    6
    Any workaround you can think of meanwhile? Looks like this bug been there forever.. don't think they will be fixing it urgently or anything. In the post you are linking they have a few ideas and one workaround where the guy downloads to file first but I can confirm that I only work with local files already and i'm still seeing these 1-2 second freezes.
     
  22. trinusvr

    trinusvr

    Joined:
    Aug 16, 2015
    Posts:
    14
    what worked for me was to add the following in MobileImporter.Import():

    ((DownloadHandlerAudioClip)webRequest.downloadHandler).streamAudio = true;

    right before the operation = webRequest.SendWebRequest();
     
    getschwiftyltd likes this.
  23. getschwiftyltd

    getschwiftyltd

    Joined:
    Aug 17, 2019
    Posts:
    6
    This is miraculous and it works. It still does a micro freeze at the first load but then any next loads work just fine! Thanks
     
  24. getschwiftyltd

    getschwiftyltd

    Joined:
    Aug 17, 2019
    Posts:
    6
    Hello again. I noticed ogg files don't play on android (VR). It seems like they load however, because the callbacks fire.. but no audio output to be heard.
    I thought it would work on android because ogg is totally supported. iOS is expected not to work with ogg. Also ogg totally plays fine on MacOSX thru BASS plugin. On Windows with NAudio it does not (as expected. no support for ogg thru NAudio).

    Any ideas for mobile importer? Thanks

    EDIT: It turns out that AudioType.MPEG is straight up hardcoded inside MobileImporter. Which makes sense for iOS. I have created a function that checks the extension of the uri and depending of that spits out the AudioType to be OGGVORBIS if it's ogg. And it worked fine. Just something to keep in mind for anyone who will stumble upon this issue.
     
    Last edited: Nov 8, 2019
  25. xNalara

    xNalara

    Joined:
    Jun 9, 2017
    Posts:
    4
    Hello Meow,
    thank you for this free package. I also purchased the Rhythm Tool. Currently, I am trying to get these two to work together.
    1. I want to read paths to audio files (mp3) from a text file (works correctly).
    2. I iterate through these paths and want to import all the files, one after another, and save them to a List<AudioClip>. (The clips can be played correctly.)
    3. I call the RhythmAnalyzer.Analyzer method with the first file, wait until the progress is 1 (I also tried the isDone and checked if it's true) and save the RhythmData to another List<RhythmData>.
    4. I play the first file, which works fine, but the analysis is incomplete for some reason, although isDone is true and the progress is 1. When I use the context menu (Right-click -> RhythmTool -> Analyze) to create the RhythmData of the mp3 file, I got 458 beats in total. But in my "runtime import and analyze"-version I only get (always!) 75 beats for my test file, so there is a lot missing. Since it's always the same amount of beats (and missing beats), I don't think that it's because of a race condition. This is the same for all imported files except the last one.
    5. For some reason which I wasn't able to figure out right now, the analysis for the last track I imported is always close to the analysis via the context menu in the Editor (+1 with my test file).
    I also tried to chain these methods in the way you suggested in the documentation (via the Initialized event and without the playlist, so with only one file). Then I get 472 beats in the runtime version instead of 458 beats in the editor analysis version.

    Do you have any idea what or where it could go wrong? (I can provide my code per mail if you think it might help you understand the problem.)
     
  26. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    I'm not sure what could be causing this issue. It would be great if you could send me some code.

    Small differences between runtime imported files and AudioClips that are part of the project are common and are caused by small differences between the different decoders. Different decoders can give slightly different audio signals. A difference of 14 detected beats seems a bit much, so maybe there is something else going on.
     
  27. xNalara

    xNalara

    Joined:
    Jun 9, 2017
    Posts:
    4
    Thank you so much for your fast response. In the meanwhile, I was able to create a minimal example to show where it breaks.
    First of all, it seems that I was wrong: the audio clips were not imported properly, this is why the analysis failed. During the debugging process, I only checked for their length, which is correct. But after some seconds there was no data in the clips anymore. This is why, of course, the analysis also seemed to fail, since there was no data to analyze.
    I realized, that I need to create a separate GameObject for each track that shall be imported, as well as a separate GameObject for each analysis. By doing this, I made it work.
    Nonetheless, there is still a problem remaining: I don't want these GameObjects in my scene all the time for performance issues, so I want to destroy them when they are not used anymore. So in the method, which listens to the importer's "Loaded" event, I delete the GameObject after it invoked this event. If I do this, the clip is not correctly imported anymore. You can try it by yourself using the code below.
    For me, it seems like the event might be invoked too early, but this is only a guess. Maybe you can give a further explanation (maybe I did something wrong!) or provide a solution to this problem?

    Code (CSharp):
    1. /* This script is attached to a GameObject with an AudioSource and a RhythmPlayer component
    2. */
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using RhythmTool;
    7. using System.IO;
    8. using UnityEditor;
    9. using NAudio;
    10.  
    11. public class MusicController : MonoBehaviour
    12. {
    13.     public List<string> importPaths; //assign some paths to audio files in the editor
    14.     public List<AudioClip> importedClips;
    15.     public RhythmEventProvider rhythmEvents;
    16.     private RhythmPlayer rhythmPlayer;
    17.     private AudioSource audioSource;
    18.     public List<GameObject> activeImporters = new List<GameObject>();
    19.     public int indexCurrentlyPlaying = 0;
    20.  
    21.     // use this bool to invoke the OnRunStarted method from the editor
    22.     public bool start = false;
    23.  
    24.     protected void OnEnable()
    25.     {
    26.         this.rhythmPlayer = this.GetComponent<RhythmPlayer>();
    27.         this.audioSource = this.GetComponent<AudioSource>();
    28.         rhythmPlayer.SongEnded += OnSongEnded;
    29.     }
    30.  
    31.     protected void OnDestroy()
    32.     {
    33.         rhythmPlayer.SongEnded -= OnSongEnded;
    34.     }
    35.  
    36.     private void Update()
    37.     {
    38.         if (audioSource.isPlaying)
    39.         {
    40.             Debug.Log(audioSource.time);
    41.         }
    42.  
    43.         if (start)
    44.         {
    45.             OnRunStarted();
    46.             start = false;
    47.         }
    48.     }
    49.  
    50.     private void OnRunStarted()
    51.     {
    52.         // reset imported clips
    53.         importedClips = new List<AudioClip>();
    54.         // create importer object
    55.         GameObject importer = new GameObject();
    56.         importer.transform.SetParent(this.transform);
    57.         importer.AddComponent<NAudioImporter>();
    58.         activeImporters.Add(importer);
    59.         // subscribe to event
    60.         importer.GetComponent<NAudioImporter>().Loaded += OnLoaded;
    61.         //import
    62.         importer.GetComponent<NAudioImporter>().Import(importPaths[importedClips.Count]);
    63.     }
    64.  
    65.     private void OnLoaded(AudioClip clip)
    66.     {
    67.         Debug.Log("Imported " + clip.name);
    68.         importedClips.Add(clip);
    69.  
    70.         if (importedClips.Count < importPaths.Count)
    71.         {
    72.             // create importer object
    73.             GameObject importer = new GameObject();
    74.             importer.transform.SetParent(this.transform);
    75.             importer.AddComponent<NAudioImporter>();
    76.             activeImporters.Add(importer);
    77.             // subscribe to event
    78.             importer.GetComponent<NAudioImporter>().Loaded += OnLoaded;
    79.             //import
    80.             importer.GetComponent<NAudioImporter>().Import(importPaths[importedClips.Count]);
    81.         }
    82.         else // last track imported
    83.         {
    84.             // clean up all the importer objects: if this is active, the files are not imported properly
    85.             // although they already invoked the Loaded event
    86.  
    87.             //foreach (GameObject go in activeImporters)
    88.             //{
    89.             //    go.GetComponent<NAudioImporter>().Loaded -= OnLoaded;
    90.             //    Destroy(go);
    91.             //}
    92.             indexCurrentlyPlaying = 0;
    93.             audioSource.clip = importedClips[indexCurrentlyPlaying];
    94.             audioSource.Play();
    95.         }
    96.     }
    97.  
    98.     private void OnSongEnded()
    99.     {
    100.         if (indexCurrentlyPlaying < importedClips.Count - 1)
    101.         {
    102.             indexCurrentlyPlaying++;
    103.             audioSource.clip = importedClips[indexCurrentlyPlaying];
    104.             audioSource.Play();
    105.         }
    106.         else
    107.         {
    108.             Debug.Log("Reached end of playlist.");
    109.         }
    110.     }
    111. }
    112.  
     
  28. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Ah, I see. The importer's Loaded event is called as soon as the AudioClip is available. This happens right after the file is opened and the AudioClip is created. This doesn't mean the file is done importing. This is done so you can start playing and analyzing the audio file as soon as possible, while the file is still being imported.

    The importer is faster than the analyzer, so this is fine if you just want to play and analyze one file. However, if you use the same importer to start importing a new file, it will stop importing the original and the AudioClip wil only have the beginning of the song.

    I think the documentation and naming could be better here. A possible workaround would be to use AudioImporter.progress, which indicates the actual progress of the importer, or to use multiple importers/analyzers.
     
  29. xNalara

    xNalara

    Joined:
    Jun 9, 2017
    Posts:
    4
    Yes, okay. Maybe you can update the documentation so this becomes more clear for everybody :)
    I would also like to suggest to add to the documentation this case (I was wondering why the file did not start to play until I figured out, that the internal _audioClip is updated in the Update() method) or you might want to add a method to call from the source code to invoke the update manually:
    Code (CSharp):
    1.         audioSource.clip = importedClips[currentlyPlayedClipIndex];
    2.         rhythmPlayer.rhythmData = analyzedClips[currentlyPlayedClipIndex];
    3.         // we need to skip a frame here, because rhythmPlayer must update internally to the new audioSource.clip
    4.         yield return null;
    5.         rhythmPlayer.Play();
    I now instantiated multiple importers and analyzers, but I still need to know when they are done. I tried to check if the progress is >= 1, but it gets stuck around 0.99.., so I cannot be sure if it's finally finished. I also tried to set it by myself to 1 inside the asset code, but it never worked out the way I wanted it to behave. Which method would you suggest to set progress to 1 or to check if the import is completed?

    Moreover, I rechecked the beats now from the runtime import and analysis and the editor analysis. They still differ a lot. On runtime, I get 472 beats while in the editor analysis it's only 458 beats. Do you have any idea what could cause this?

    Thank you so much in advance!
     
  30. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    When playing an AudioClip with a RhythmPlayer, it's better to assign it to the RhythmPlayer directly like this:
    Code (CSharp):
    1. rhythmPlayer.audioClip = clip;
    The issue with AudioImporter.progress probably is an old bug that hasn't made it to the asset store version yet. I haven't updated it in a while. You can get the most recent version here: https://github.com/Hello-Meow/AudioImporter

    Differences between runtime imported songs and songs that are imported into the project are probably caused by the small differences between Unity's importer and NAudio. Small differences in the audio signal can lead to different analysis results in some cases.
     
  31. xNalara

    xNalara

    Joined:
    Jun 9, 2017
    Posts:
    4
    Thank you, it works perfectly now!
     
  32. Stader

    Stader

    Joined:
    Jun 8, 2018
    Posts:
    15
    is it possible to import audios in .wav?
     
  33. Kagyu

    Kagyu

    Joined:
    Mar 5, 2016
    Posts:
    95
    Hi Hello Mellow,
    Thanks for the plugin . I noticed that the importing process does not properly work when I build the project in IL2CPP though it works fine in the Editor.
    If possible, can you fix that please.
     
  34. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    NAudio is incompatible with il2cpp, so unfortunately there is no way to fix that. BassImporter might work, so it could be worth it to look into that.
     
  35. Kagyu

    Kagyu

    Joined:
    Mar 5, 2016
    Posts:
    95
    Got it. I will give a try BASS if its license is suitable for my use case. I will check the license.
    Thanks1
     
  36. jakethehuman

    jakethehuman

    Joined:
    Oct 3, 2014
    Posts:
    7
    I got an error while playing the standalone build:

    Code (CSharp):
    1. Custom marshaler 'WaveFormatCustomMarshaler' does not implement a static GetInstance method that takes a single string parameter and returns an ICustomMarshaler.
    2. UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
    3. UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    4. UnityEngine.Logger:Log(LogType, Object)
    5. UnityEngine.Debug:LogError(Object)
    6. <Import>d__5:MoveNext() (at D:\documents\ccs\Assets\AudioImporter\Examples\ImporterExample.cs:30)
    7. UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) (at C:\buildslave\unity\build\Runtime\Export\Scripting\Coroutines.cs:17)
    8. (Filename: D:/documents/ccs/Assets/AudioImporter/Examples/ImporterExample.cs Line: 30)
    Although it works perfectly in Editor.
     
  37. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Which platform, scripting runtime and backend are you using?
     
  38. jakethehuman

    jakethehuman

    Joined:
    Oct 3, 2014
    Posts:
    7
    it was for Windows, Mono and .NET 4.x btw
     
  39. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Hmmm, this seems like the kind of error you might expect when using the wrong runtime or platform, but that's not the case here. I don't know why you're getting this issue. Can you test it on another PC?
     
  40. martial_loh

    martial_loh

    Joined:
    Nov 7, 2015
    Posts:
    1
    Hi Tim, I was wondering what changes you suggested one of your reviewers make to the Editor example code to access the USB folders of his Oculus Go device? I'm wondering the same thing (but this time on the Oculus Quest 2).
    Thanks!

    EDIT - after a little digging and guessing, this worked - change the currentDirectory line in the Awake section of the Browser script to -
    currentDirectory = "sdcard";
     
    Last edited: Nov 2, 2020
  41. simonejennings

    simonejennings

    Joined:
    Jan 11, 2017
    Posts:
    13
    @HelloMeow Great asset! super helpful on getting audio loading working on windows and android!
    Any plans to support mac or webgl in the future?
    If not are there any changes you know of that I could make to get it to work for those platforms?

    Thanks
     
  42. ScottNguyen

    ScottNguyen

    Joined:
    May 30, 2020
    Posts:
    2
    Hi, when I import AudioImporter into my project, an error immediately appears in my console. How to fix it?. I use Windows, IL2CPP, .NET Standard 2.0 and unity ver 2019.4.15f1. Tks
     

    Attached Files:

    • 1.PNG
      1.PNG
      File size:
      24.2 KB
      Views:
      351
    • 2.PNG
      2.PNG
      File size:
      53.8 KB
      Views:
      327
  43. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Mac might be supported by BassImporter if you use the platform specific libraries. Unfortunately WebGL was too restrictive the last time I tried to get it to work.

    I'm not sure what could be causing this. Does it also give this error on other platforms or without IL2CPP?
     
    simonejennings likes this.
  44. Lags30

    Lags30

    Joined:
    Mar 4, 2016
    Posts:
    1
    Why am i stuck in this folders and cannot see any file or get to a familiar location like the sd card ? am i missing something? do i need to create a custom browser script? or is a thing about permissions?


    EDIT: It was a permission issue , if someone else has this problem as well
     

    Attached Files:

    Last edited: Jul 8, 2021
  45. wadimaks

    wadimaks

    Joined:
    Aug 23, 2020
    Posts:
    1
    What permissions did you get and how? Everything works for me on Android 6, but does not work on Android 10.
     
  46. S_Darkwell

    S_Darkwell

    Joined:
    Oct 20, 2013
    Posts:
    320
    Hello @HelloMeow,

    Firstly, thank you for your fantastic package! It is far and away an easier approach than any others I see out there.

    There is one challenge that I am having—how can I use your scripts to load an entire directory of .wav files into an array or list? I've tried a number of approaches, but all either result in either a single or no files actually loading.

    Is there any potential you could offer a simple example?

    Thank you in advance and be well!
    - S.
     
  47. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    For .wav files you don't need to use this package. You can just use UnityWebRequestMultimedia.GetAudioClip. Also, depending on the number of files and the length of the files, loading entire directories can eat up a lot of memory really fast, so that might be a bad idea.

    You'd probably want to load the files in parallel, as loading them one by one would be much slower. I'd first get a list of the .wav files with Directory.GetFiles and then start a coroutine for each file, that imports it and adds the clip it to a list.

    If you have to use AudioImporter, you'd need one importer component for each file. An importer can only import one file at a time. If you call Import when it's still importing another file, it will stop importing and start over for the new file.
     
    S_Darkwell likes this.
  48. S_Darkwell

    S_Darkwell

    Joined:
    Oct 20, 2013
    Posts:
    320
    Hello @HelloMeow,

    Thank you so much. That definitely helps! I've managed to get it to work, so it's all just optimization from here.

    Many thanks again and be well!
    - S.
     
  49. spikezart

    spikezart

    Joined:
    Oct 28, 2021
    Posts:
    72
    Hi there, I'm running version 2022.3.1f1 and have a couple of errors that suggest obsolete parts to the code:

    Assets/AudioImporter/Scripts/MobileImporter.cs(51,49): warning CS0618: 'UnityWebRequest.isHttpError' is obsolete: 'UnityWebRequest.isHttpError is deprecated. Use (UnityWebRequest.result == UnityWebRequest.Result.ProtocolError) instead.'

    and

    Assets/AudioImporter/Scripts/MobileImporter.cs(51,20): warning CS0618: 'UnityWebRequest.isNetworkError' is obsolete: 'UnityWebRequest.isNetworkError is deprecated. Use (UnityWebRequest.result == UnityWebRequest.Result.ConnectionError) instead.'

    is it possible to update this sometime?

    Thanks
     
  50. spikezart

    spikezart

    Joined:
    Oct 28, 2021
    Posts:
    72
    For anyone else wondering, I just found that the following seems to successfully replace the obsoletes:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.Networking;
    4.  
    5. /// <summary>
    6. /// A component for importing audio files on Android and iOS.
    7. /// </summary>
    8. [AddComponentMenu("AudioImporter/Mobile Importer")]
    9. public class MobileImporter : AudioImporter
    10. {
    11.     private UnityWebRequest webRequest;
    12.     private AsyncOperation operation;
    13.    
    14.     public override float progress
    15.     {
    16.         get
    17.         {
    18.             if (operation == null)
    19.                 return 0;
    20.  
    21.             return operation.progress;
    22.         }
    23.     }
    24.  
    25.     public override bool isDone
    26.     {
    27.         get
    28.         {
    29.             if (operation == null)
    30.                 return false;
    31.  
    32.             return operation.isDone;
    33.         }
    34.     }
    35.  
    36.     public override bool isInitialized
    37.     {
    38.         get
    39.         {
    40.             return isDone;
    41.         }      
    42.     }
    43.  
    44.     public override bool isError
    45.     {
    46.         get
    47.         {
    48.             if (webRequest == null)
    49.                 return false;
    50.  
    51.             return webRequest.result == UnityWebRequest.Result.ConnectionError || webRequest.result == UnityWebRequest.Result.ProtocolError;
    52.         }
    53.     }
    54.  
    55.  
    56.     public override string error
    57.     {
    58.         get
    59.         {
    60.             if (webRequest == null)
    61.                 return string.Empty;
    62.  
    63.             return webRequest.error;
    64.         }
    65.     }
    66.    
    67.     /// <summary>
    68.     /// Stop importing as soon as possible.
    69.     /// </summary>
    70.     public override void Abort()
    71.     {
    72.         if (webRequest != null)
    73.         {
    74.             webRequest.Abort();
    75.             webRequest.Dispose();
    76.             webRequest = null;
    77.  
    78.             StopAllCoroutines();
    79.         }  
    80.     }
    81.  
    82.     protected override void Import()
    83.     {
    84.         webRequest = UnityWebRequestMultimedia.GetAudioClip(uri.AbsoluteUri, AudioType.UNKNOWN);
    85.         operation = webRequest.SendWebRequest();
    86.  
    87.         StartCoroutine(WaitForWebRequest());
    88.     }
    89.    
    90.     IEnumerator WaitForWebRequest()
    91.     {
    92.         yield return operation;
    93.  
    94.         audioClip = DownloadHandlerAudioClip.GetContent(webRequest);
    95.  
    96.         webRequest.Dispose();
    97.         webRequest = null;
    98.  
    99.         OnLoaded();
    100.     }
    101. }
    102.