25

I'm creating an app for Android, iOS and Windows Phone using Xamarin.forms. My question is how to play a mp3 or wav with Xamarin Forms?

My business logic is handled by Shared Project and I don't know how to use platform specifically "MediaPlayer".

1

5 Answers 5

16

Right now Xamarin.forms has not sound API, so you need to use DependencyService

Check the following link, it is working fine for me:

https://www.codeproject.com/Articles/1088094/Playing-audio-mp-File-in-Xamarin-Forms

We would require to create an Interface which will be implemented in platform specific project, I named it as IAudio.cs and the code for the same is as follows:

using System;
  namespace AudioPlayEx
   {
    public interface IAudio
        {
            void PlayAudioFile(string fileName);
        }
   }

Android Solution:

    using System;
    using Xamarin.Forms;
    using AudioPlayEx.Droid;
    using Android.Media;
    using Android.Content.Res;

    [assembly: Dependency(typeof(AudioService))]
    namespace AudioPlayEx.Droid
    {
        public class AudioService: IAudio
        {
            public AudioService ()
            {
            }

            public void PlayAudioFile(string fileName){
                var player = new MediaPlayer();
                var fd = global::Android.App.Application.Context.Assets.OpenFd(fileName);
                player.Prepared += (s, e) =>
                {
                    player.Start();
                };
                player.SetDataSource(fd.FileDescriptor,fd.StartOffset,fd.Length);
                player.Prepare();
            }
        }
}

iOS Solution:

using System;
using Xamarin.Forms;
using AudioPlayEx;
using AudioPlayEx.iOS;
using System.IO;
using Foundation;
using AVFoundation;

[assembly: Dependency (typeof (AudioService))]
namespace AudioPlayEx.iOS
{
    public class AudioService : IAudio
    {
        public AudioService ()
        {
        }

        public void PlayAudioFile(string fileName)
        {
            string sFilePath = NSBundle.MainBundle.PathForResource
            (Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName));
            var url = NSUrl.FromString (sFilePath);
            var _player = AVAudioPlayer.FromUrl(url);
            _player.FinishedPlaying += (object sender, AVStatusEventArgs e) => {
                _player = null;
            };
            _player.Play();
        }
    }
}

And finally, we will use the following code in our PCL/shared project in order to play the audio file.

DependencyService.Get<IAudio>().PlayAudioFile("MySong.mp3");
2
15

You might give Xam.Plugin.SimpleAudioPlayer a try, since Xamarin.Forms doesn't have a sound API.

In short, add the NuGet package to each platform-specific project you wish to support. Copy the audio files to the Assets folder for Windows UWP and Android and set the build actions as Content and Android Asset respectively. For iOS copy the audio files to the Resources folder and set the build action to BundleResource, then play the files like so:

var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current; 
player.Load("intro_sound.mp3");
player.Play();
2
9

I just finished creating an AudioManager for Xamarin that works on iOS, Android, UWP, Windows 8.1, and Windows Phone 8.1. If you are interested check it out at https://github.com/jcphlux/XamarinAudioManager. There is a link to a Nuget package or feel free to clone the project.

2
  • Are you still updating your project ? Commented Nov 1, 2018 at 22:20
  • 1
    I have moved away from using Xamarin. I have been using Ionic for my mobile solutions. I have not updated it in the past 2 years. If someone want to work on an update for it I will take a pull request. Sorry.
    – JCPhlux
    Commented Nov 16, 2018 at 19:38
6

I think, Xamarin.Forms has no sound APIs at the moment so you will have to write custom, platform-specific code.

Check how James Montemagno implements TextToSpeech (using DependencyService)

Refer :

1

Use a dependency service to play the sounds through the native platforms. If you only need to play one sound at a time, you can use static fields to manage the lifetime of the player objects. The static fields prevent the player from be destroyed and the audio to stop if a garbage collection occurs while the audio is playing.

The following approach plays one sound at a time, with any new sound terminating and replacing any previous sound.

Create an interface for a dependency service:

public interface IAudio {
    void PlayAudioFile(string fileName);
}

Use the dependency service where you want to play the sound:

DependencyService.Get<IAudio>().PlayAudioFile("honk.mp3");

This is the dependency service for iOS:

using AVFoundation;
using Foundation;
using System.IO;
using Xamarin.Forms;

[assembly: Dependency(typeof(AudioService))]
public class AudioService : IAudio {
    static AVAudioPlayer player;

    public void PlayAudioFile(string fileName) {
        var url = NSUrl.FromString(NSBundle.MainBundle.PathForResource(Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName)));
        player = AVAudioPlayer.FromUrl(url);
        player.FinishedPlaying += (sender, e) => { player = null; };
        player.Play();
    }
}

This is the dependency service for Android:

using Xamarin.Forms;
using Android.Media;

[assembly: Dependency(typeof(AudioService))]
public class AudioService : IAudio {
    static MediaPlayer player;

    public void PlayAudioFile(string fileName) {
        player?.Stop();
        player = new MediaPlayer();
        var fd = Android.App.Application.Context.Assets.OpenFd(fileName);
        player.SetDataSource(fd.FileDescriptor, fd.StartOffset, fd.Length);
        player.Prepared += (s, e) => player.Start();
        player.Completion += (s, e) => { player = null; };
        player.Prepare();
    }
}
1
  • Thanks to @MikeDarwish for his answer showing the native calls to use. Commented May 20, 2021 at 19:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.