如何在Xamarin.forms上播放声音

本文关键字:播放声音 forms Xamarin | 更新日期: 2023-09-27 18:26:34

我正在使用Xamarin.forms为Android、iOS和Windows Phone创建一个应用程序。我的问题是如何使用Xamarin forms播放mp3或wav?

我的业务逻辑是由共享项目处理的,我不知道如何使用专门的"MediaPlayer"平台。

如何在Xamarin.forms上播放声音

现在Xamarin.forms没有声音API,因此您需要使用DependencyService

检查以下链接,它对我来说运行良好:

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

我们需要创建一个接口,该接口将在特定平台的项目中实现,我将其命名为IAudio.cs,其代码如下:

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

安卓解决方案:

    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解决方案:

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();
        }
    }
}

最后,我们将在PCL/共享项目中使用以下代码来播放音频文件。

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

您可以尝试Xam.Plugin.SimpleAudioPlayer,因为Xamarin.Forms没有一个健全的API。

简而言之,将NuGet包添加到您希望支持的每个特定于平台的项目中。将音频文件复制到Windows UWP和Android的Assets文件夹中,并将构建操作分别设置为ContentAndroid Asset。对于iOS,将音频文件复制到Resources文件夹,并将构建操作设置为BundleResource,然后播放如下文件:

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

我刚刚为Xamarin创建了一个适用于iOS、Android、UWP、Windows 8.1和Windows Phone 8.1的AudioManager。如果您感兴趣,请访问https://github.com/jcphlux/XamarinAudioManager.有一个指向Nuget包的链接,或者可以随意克隆该项目。

我认为,Xamarin.Forms目前没有健全的API,因此您将不得不编写自定义的、特定于平台的代码

检查James Montemagno如何实现TextToSpeech(使用DependencyService)

参考:

  • Xamarin.Forms:SimpleAudioForms中的音频样本
  • James Montemagno的TextToSpeech

使用依赖服务通过本地平台播放声音。如果一次只需要播放一个声音,则可以使用静态字段来管理播放器对象的生存期。如果在播放音频时发生垃圾收集,则静态字段可防止播放器被破坏,并防止音频停止。

以下方法一次播放一个声音,任何新的声音都会终止并替换任何以前的声音。

为依赖服务创建接口:

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

使用您想要播放声音的依赖服务:

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

这是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();
    }
}

这是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();
    }
}