Search Unity

byte array to audio clip?

Discussion in 'Web' started by omriperll, Feb 14, 2018.

  1. omriperll

    omriperll

    Joined:
    Aug 14, 2017
    Posts:
    15
    Hi :)
    I need to load a local ogg audio file (represented as a byte array) and convert it to an audio clip.
    I tried to access the file using the 'WWW' class but wasn't able to retrieve it correctly (it was corrupted)
    Is that even possible in WebGL ?

    Thanks!
     
  2. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
    this works for me:
    Code (CSharp):
    1.             WWW data = new WWW (url);
    2.             yield return data;
    3.             try
    4.             {
    5.                 AudioClip ac = data.GetAudioClipCompressed(false, AudioType.AUDIOQUEUE) as AudioClip;
    6.                 if(ac != null)
    7.                 {
    8.                     ac.name = "mySoundFile.ogg";
    9.                 }
    10.                 else
    11.                 {
    12.                     Debug.Log("no audio found.");
    13.                 }
    14.             }
    15.             catch (System.Exception e)
    16.             {
    17.                 Debug.Log(e);
    18.             }
     
  3. omriperll

    omriperll

    Joined:
    Aug 14, 2017
    Posts:
    15
    Hi sumpfkraut,
    This works for a url, but I need to load an audio file from the hard drive - not from a url
     
  4. omriperll

    omriperll

    Joined:
    Aug 14, 2017
    Posts:
    15
    I can't seem to use WWW correctly to load a file that is stored locally on indexed db. The only thing I can think of is finding some kind of algorithm that will transform the byte array to an audio clip
     
  5. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
  6. omriperll

    omriperll

    Joined:
    Aug 14, 2017
    Posts:
    15
    Can you point me for a working example on how to use the file path/blob option? I wasn't able to find any that works
     
  7. omriperll

    omriperll

    Joined:
    Aug 14, 2017
    Posts:
    15
    Thanks, I checked it out, but there is no source code there, also the files are not saved in indexed db, you just save them yourself on the hard drive.
    What I'm looking for is something like this (2 options):
    1.Read a locally saved audio file(ogg format) into a byte array (this works ok)
    2.Convert the byte array to some float array that can be used to create an audio clip (no idea how to do this)
    --------or------------

    1.Read a locally saved audio file using the WWW class (I tried to do this but with no success)
    2.Use the 'GetAudioClip' method to get the audio clip

    Hope this is clearer now :)
     
  8. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
    i hope this helps...

    In your C# code:
    Code (CSharp):
    1. #if UNITY_WEBGL
    2. using System.Runtime.InteropServices;
    3. #endif
    4. ...
    5. ...
    6. #if UNITY_WEBGL
    7.         [DllImport("__Internal")]
    8.         private static extern void SoundUploader(string gameObjectName, string voidName);
    9. #endif
    10.  
    11.         private void LoadOgg() // <- Start this to load a ogg file from your hard drive.
    12.         {
    13. #if UNITY_WEBGL
    14.             SoundUploader(gameObject.name, "LoadOggInWebGL");
    15. #endif
    16.         }
    17.  
    18.         private IEnumerator LoadOggInWebGL(string url) // URL as BLOB from the jslib plugin (SoundUploader.jslib)
    19.         {
    20. #if UNITY_WEBGL
    21.             WWW data = new WWW(url); yield return data;
    22.             try
    23.             {
    24.                 AudioClip ac = data.GetAudioClipCompressed(false, AudioType.AUDIOQUEUE) as AudioClip;
    25.                 if (ac != null)
    26.                 {
    27.                     ac.name = "mySoundFile.ogg";
    28.                     gameObject.GetComponent<AudioSource> ().clip = ac;
    29.                 }
    30.                 else
    31.                 {
    32.                     Debug.Log("no audio found.");
    33.                 }
    34.             }
    35.             catch (System.Exception e)
    36.             {
    37.                 Debug.Log(e);
    38.             }
    39. #endif
    40.     }

    SoundUploader.jslib in the Assets/Plugins folder
    Code (JavaScript):
    1. var SoundUploaderPlugin =
    2. {
    3.   SoundUploader: function(gObj, vName)
    4.   {
    5.     var gameObj = Pointer_stringify(gObj);
    6.     var voidName = Pointer_stringify(vName);
    7.     if (!document.getElementById('SoundUploaderInput'))
    8.     {
    9.       var fileInput = document.createElement('input');
    10.       fileInput.setAttribute('type', 'file');
    11.       fileInput.setAttribute('id', 'SoundUploaderInput');
    12.       fileInput.setAttribute('accept', '.ogg');
    13.       fileInput.style.visibility = 'hidden';
    14.       fileInput.style.display = 'none';
    15.       fileInput.onclick = function (event)
    16.       {
    17.         this.value = null;
    18.       };
    19.       fileInput.onchange = function (event)
    20.       {
    21.         blob = ((window.URL || window.webkitURL) || URL).createObjectURL(event.target.files[0]);
    22.         gameInstance.SendMessage(gameObj, voidName, blob);
    23.         document.getElementById("SoundUploaderInput").remove();
    24.       };
    25.       document.body.appendChild(fileInput);
    26.     }
    27.     else
    28.     {
    29.       //alert('SoundUploaderInput already exist...');
    30.     }
    31.     var blob = null;
    32.     var OpenFileDialog = function() {
    33.         $("#SoundUploaderInput").click();
    34.         document.getElementById('gameContainer').removeEventListener('click', OpenFileDialog);
    35.     };
    36.     document.getElementById('gameContainer').addEventListener('click', OpenFileDialog, false);
    37.   }
    38. };
    39. mergeInto(LibraryManager.library, SoundUploaderPlugin);

    - you have to click twice to get the file dialog in WebGL.

    EDIT
    it's possible that you can not use a IEnumerator direct from the .jslib
    then try this:
    Code (CSharp):
    1. private void LoadOggInWebGL(string url)
    2. {
    3.     StartCoroutine(LoadOggInWebGL2(url));
    4. }
    5.  
    6. private IEnumerator LoadOggInWebGL2(string url)
    7. {
    8. //....
    9. }
     
    Last edited: Feb 15, 2018
  9. omriperll

    omriperll

    Joined:
    Aug 14, 2017
    Posts:
    15
    Looks very interesting:):):) I'll try it and let you know!
     
  10. omriperll

    omriperll

    Joined:
    Aug 14, 2017
    Posts:
    15
    I can read the file with WWW now!!
    The audio clip is still not working but its huge progress for me, thanks:):):):):)
     
  11. SaintGrey

    SaintGrey

    Joined:
    Jul 17, 2014
    Posts:
    2
    Hi, guys.

    I have online/offline project.
    I need to download wav/ogg/mp3 file from Application.persistentDataPath on WebGL platform.
    I tried www/webrequest.
    For example - WWW("file://" + Application.persistentDataPath + filePath);

    But always get error: Failed to load: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

    Could you help me?

    P.S. From remote server works fine.
     
    Last edited: Feb 26, 2018
  12. Marco-Trivellato

    Marco-Trivellato

    Unity Technologies

    Joined:
    Jul 9, 2013
    Posts:
    1,654
    I think the best way to do this is by using Streaming Assets.
     
  13. SaintGrey

    SaintGrey

    Joined:
    Jul 17, 2014
    Posts:
    2
    Unfortunately, Streaming Assets folder is located on the remote server and without internet I can't load data from there.