Sjors Miltenburg
Sjors Miltenburg

Reputation: 2750

play a downloaded mp3 in xamarin forms

I am able to play a file "test.mp3" added as a resource into the "Resources\Sounds\" folder of my pcl project by calling

AudioManager.Audio.Manager.PlaySound("test.mp3");

Now I am trying to play an audio file that I have downloaded from my webapi service. I am using the RestSharp library to download the file and the PCLStorage library to store the file:

try
            {
                var fileId = new Guid("test2");
                IFolder rootFolder = FileSystem.Current.LocalStorage;
                IFolder resources = await rootFolder.CreateFolderAsync("Resources", CreationCollisionOption.OpenIfExists);
                IFolder soundsFolder = await rootFolder.CreateFolderAsync("Sounds", CreationCollisionOption.OpenIfExists);
                IFile myFile = await soundsFolder.CreateFileAsync($"{fileId}.mp3", CreationCollisionOption.ReplaceExisting);
                using (var stream = await myFile.OpenAsync(fileAccess: FileAccess.ReadAndWrite))
                {

                var request = new RestRequest($"{fileId}");
                var client = new RestClient();
                client.BaseUrl = new System.Uri("http://10.0.2.2/MyApp.WebApi/api/");
                var bytes = client.DownloadData(request);
                foreach (var myByte in bytes)
                {
                    stream.WriteByte(myByte);
                }
            }
        }
        catch (Exception e)
        {

        }

I also tried saving the file to the root dir but this also doesn't work.

The file seems to download just fine as far as I can tell (no errors). But I have yet to find a way to verify this by locating the file on the android emulator. I guess I first need to install the play store somehow and then download ES File explorer to see the file structure on the android emulator.

The problem is that when I try to play the soundfile in the same way I did with the embedded resource it won't work.

AudioManager.Audio.Manager.PlaySound("test2.mp3");

I guess this is because of the magic that happens during compile time to migrate the embedded resources to "somewhere" on the android emulator. My main problem is that I do not understand what path to use to

in order to be able to play the file

Upvotes: 0

Views: 963

Answers (1)

Sjors Miltenburg
Sjors Miltenburg

Reputation: 2750

It turns out the AudioManager library assumes sounds are always Assets. In it's NewSound method in the android code it tries to build an AssetFileDescriptor by using the following line:

Forms.Context.Assets.OpenFd(filePath);

I guess this method wants a filepath relative to the assets folder (for compiled resources) and throws a FileNotFoundException otherwise. This exception, however thrown, did not reach my catch statement in my pcl code. (it looks like it get's swallowed somewhere in the android -> pcl layer??)

Now I am using the SoundPool.LoadAsync with a filepath rather than a AssetFileDescriptor and this fixes my problem.

Yay!

Upvotes: 1

Related Questions