4

Okay, I have this problem for almost a month now. Some audio files are not playing. It just returns an error like this:

Could not initialize an instance of the type 'AVFoundation.AVAudioPlayer': the native 'initWithContentsOfURL:error:' method returned nil.

Here's the code initialising the AudioPlayer:

    NSData data = new NSData();
    if (AppSession.IsConnected ()) {/*Just a checker if connection is available or not*/
        if (uri != null && uri.ToString().Length > 0) {
            data = await LoadData (uri);
        }
    } else { data = null; }

    string saveFile = FolderPath(uri, "playthrough");
    data.Save(saveFile, false);
    NSUrl fileUrl = NSUrl.FromString(saveFile);
    audioplayer = AVAudioPlayer.FromUrl(fileUrl);
    audioplayer.NumberOfLoops = 0;
    audioplayer.Volume = 1.5f;
    audioplayer.PrepareToPlay();
    audioplayer.Play();

For LoadData:

    public static async Task<NSData> LoadData (NSUrl url)
    {
        NSData data = new NSData ();
        if (url.ToString ().Contains ("http")) {
            var httpClient = new HttpClient ();
            Task<byte[]> contentsTask = httpClient.GetByteArrayAsync (url.ToString ());
            var contents = await contentsTask;
            data = NSData.FromArray(contents);
        } else { data = NSData.FromUrl (url); }
        return data;
    }

For FolderPath:

    public static string FolderPath(NSUrl url, string fileName)
    {
        string[] dotSplitter = url.ToString ().Split (new char[]{ '.' }, 4);
        string ext = "";
        if (dotSplitter.Length == 4) {
            switch (dotSplitter [3]) {
            case "wav": ext = ".wav"; break;
            case "mp3": ext = ".mp3"; break;
            case "3gpp": ext = ".3gpp"; break;
            case "mp4": ext = ".mp4"; break;
            }
        } else {
            switch (dotSplitter [0]) {
            case "wav": ext = ".wav"; break;
            case "mp3": ext = ".mp3"; break;
            case "3gpp": ext = ".3gpp"; break;
            case "mp4": ext = ".mp4"; break;
            }
        }

        return Path.Combine(TMPDir(), fileName + ext);
    }

And here are the files I'm using to test the audio:

So, yeah. I've done dozens of research, google, experiment and tears for this, but I ended up with no result at all. Any solutions for this?

TrieNoir
  • 53
  • 1
  • 1
  • 8

1 Answers1

2

The full exception you should get is:

System.Exception : Could not initialize an instance of the type 'MonoTouch.AVFoundation.AVAudioPlayer': the native 'initWithContentsOfURL:error:' method returned nil. It is possible to ignore this condition by setting MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure to false.

Following the above advice (use the overload accepting an NSError) and the one from the exception message you get something like:

MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure = false;
NSError error;
using (var url = NSUrl.FromString ("http://files.parsetfss.com/6ea4a3c5-a4e2-463f-8374-247d5db0fbd5/tfss-c7db3001-b7b0-465d-b59b-233c1fe568ec-filtered_427201531308PM_song.wav"))
using (var player = AVAudioPlayer.FromUrl (url, out error)) {
    Console.WriteLine (error);
}

You'll get:

The operation couldn’t be completed. (OSStatus error 2003334207.)

which is a very common error for AVAudioPlayer. I also get the same error if you use an NSData (local file). However AVPlayer loads the URL just fine...

poupou
  • 43,413
  • 6
  • 77
  • 174
  • What do you mean AVPlayer loads the URL just fine? Before using AVAudioPlayer, I used the AVAsset/AVPlayerItem/AVPlayer combo to stream the file and ended up with no luck. Please clarify. – TrieNoir May 08 '15 at 07:54