Search Unity

Saving Audio to Applications.persistentDataPath error

Discussion in 'iOS and tvOS' started by nathanjams, Sep 22, 2017.

  1. nathanjams

    nathanjams

    Joined:
    Jul 27, 2016
    Posts:
    304
    Hello,

    I'm trying to save a recorded audio file made on an iOS device so it can be emailed through this script http://answers.unity3d.com/questions/1184875/email-attachment-on-android-ios.html

    The code I am using to save/load is from here: http://shinerightstudio.com/recording-and-playing-audio-in-unity/

    or rather, here: https://github.com/casd82/Unity-Scripts/blob/master/AudioClipSerializer.cs

    As is, this script works when i run this on my OSX computer in Unity's editor. However, when I try this on iOS it doesn't work. The aforementioned email code works (except it doesn't add the attachment because it can't find the path for the audio file (which, actually, hasn't been written yet because it can't find a path to save it to)).

    Here is the code I am using to save the audio. I am sure it has to do with the path as this is the error XCode throws when I try to save the audio file "DirectoryNotFoundException: Could not find a part of the path" (I have posted the rest of the XCode error below). I've looked around for the last day and a half and can't get my head around this. This issue seems to occur regularly but none of the answers have seemed to help:

    Code (CSharp):
    1. {
    2.     //Load AudioClip from a local binary file and set it to audioSource
    3.     public static void LoadAudioClipFromDisk(AudioSource audioSource, string filename)
    4.     {
    5.         if (File.Exists (Application.persistentDataPath + "/StreamingAssets/Audio/"+ filename))
    6.         {
    7.  
    8.             //deserialize local binary file to AudioClipSample
    9.             BinaryFormatter bf = new BinaryFormatter ();
    10.             FileStream file = File.Open (Application.persistentDataPath + "/StreamingAssets/Audio/" + filename, FileMode.Open);
    11.             AudioClipSample clipSample = (AudioClipSample) bf.Deserialize (file);
    12.             file.Close ();
    13.  
    14.             //create new AudioClip instance, and set the (name, samples, channels, frequency, [stream] play immediately without fully loaded)
    15.             AudioClip newClip = AudioClip.Create(filename, clipSample.samples, clipSample.channels, clipSample.frequency, false);
    16.  
    17.             //set the acutal audio sample to the AudioClip (sample, offset)
    18.             newClip.SetData (clipSample.sample, 0);
    19.  
    20.             //set to the AudioSource
    21.             audioSource.clip = newClip;
    22.         }
    23.         else
    24.         {
    25.             Debug.Log("File Not Found!");
    26.         }
    27.  
    28.     }
    29.  
    30.     public static void SaveAudioClipToDisk(AudioClip audioClip, string filename)
    31.     {
    32.         //create file
    33.         BinaryFormatter bf = new BinaryFormatter ();
    34.         FileStream file = File.Create (Application.persistentDataPath+ "/StreamingAssets/Audio/" + filename + ".wav");
    35.  
    36.         //serialize by setting the sample, frequency, samples, and channels to the new AudioClipSample instance
    37.         AudioClipSample newSample = new AudioClipSample();
    38.         newSample.sample = new float[audioClip.samples * audioClip.channels];
    39.         newSample.frequency = audioClip.frequency;
    40.         newSample.samples = audioClip.samples;
    41.         newSample.channels = audioClip.channels;
    42.  
    43.         //get the actual sample from the AudioClip
    44.         audioClip.GetData (newSample.sample, 0);
    45.  
    46.  
    47.         bf.Serialize (file, newSample);
    48.         file.Close ();
    49.     }
    50.  
    51.     [Serializable]
    52.     class AudioClipSample
    53.     {
    54.         public int frequency;
    55.         public int samples;
    56.         public int channels;
    57.         public float[] sample;
    58.     }
    59. }

    Also, if this helps, this is the error I get in Xcode when I try to save the recorded audio file:
    If you've read this far, thank you for your time.

    Nathan
     
    Last edited: Sep 22, 2017
    akaBase likes this.
  2. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    Did you check if this entire directory chain actually exists on the device?

    My guess would be that the "/StreamingAssets/Audio/" part doesn't exist in Application.persistentDataPath and you need to create it prior creating a file in there.

    BTW, where is this "Utifiytc" coming from in the path?
     
  3. nathanjams

    nathanjams

    Joined:
    Jul 27, 2016
    Posts:
    304
    Thanks for your reply, @Peter77

    This is my first week dealing with iOS dev. so I have no idea if the directory chain exists on the device. The original code only lists "/" for the path:
    Code (CSharp):
    1. (File.Create (Application.persistentDataPath+ "/" + filename);
    However, that threw a "Sharing Violation" error. It worded in Unity's Editor but not on the iPad. I'll look into finding out what directories exist on the device and how to create one. That seems like a logical conclusion.

    As for the "Utifiytc" file name (Utifytc = filename - it was my por choice of a file name while testing, sorry for the confusion), I have a basic script that records audio input from a microphone to an AudioSource.

    Thanks for your help,

    Nathan
     
    Last edited: Sep 22, 2017