Xamarin Forms异步播放声音

时间:2016-11-01 18:17:47

标签: c# audio xamarin xamarin.ios task

我可以使用Xamarin表单(Android和iOS)成功播放声音,但我还需要实现以下目标:

  • 我需要等待,如果有多个声音被播放,那么将在下一个之前完成。
  • 我需要返回一个布尔值来指示操作是否成功。

这是我目前的简化代码(适用于iOS平台):

    public Task<bool> PlayAudioTask(string fileName)
    {
        var tcs = new TaskCompletionSource<bool>();

        string filePath = NSBundle.MainBundle.PathForResource(
                Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName));

        var url = NSUrl.FromString(filePath);

        var _player = AVAudioPlayer.FromUrl(url);

        _player.FinishedPlaying += (object sender, AVStatusEventArgs e) =>
            {
                _player = null;
                tcs.SetResult(true);
            };

        _player.Play();

        return tcs.Task;
    }

为了测试方法,我试过这样调用它:

    var res1 = await _audioService.PlayAudioTask("file1");
    var res2 = await _audioService.PlayAudioTask("file2");
    var res3 = await _audioService.PlayAudioTask("file3");

我原本希望听到file1的音频,然后是file2,然后是file3。但是我只听到文件1,代码似乎没有到达第二个等待。

三江源

1 个答案:

答案 0 :(得分:0)

我认为您的问题是AVAudioPlayer _player在完成之前已被清除。如果您要为FinsihedPlaying添加调试,您会注意到您从未达到过这一点。

尝试这些更改后,我私下AVAudioPlayer坐在Task

之外

(我使用以下指南作为参考https://developer.xamarin.com/recipes/ios/media/sound/avaudioplayer/

    public async void play()
    {

        System.Diagnostics.Debug.WriteLine("Play 1");
        await PlayAudioTask("wave2.wav");

        System.Diagnostics.Debug.WriteLine("Play 2");
        await PlayAudioTask("wave2.wav");

        System.Diagnostics.Debug.WriteLine("Play 3");
        await PlayAudioTask("wave2.wav");

    }


    private AVAudioPlayer player;  // Leave the player outside the Task

    public Task<bool> PlayAudioTask(string fileName)
    {
        var tcs = new TaskCompletionSource<bool>();

        // Any existing sound playing?
        if (player != null)
        {
            //Stop and dispose of any sound
            player.Stop();
            player.Dispose();
        }

        string filePath = NSBundle.MainBundle.PathForResource(
                Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName));

        var url = NSUrl.FromString(filePath);

        player = AVAudioPlayer.FromUrl(url);

        player.FinishedPlaying += (object sender, AVStatusEventArgs e) =>
        {
            System.Diagnostics.Debug.WriteLine("DONE PLAYING");
            player = null;
            tcs.SetResult(true);
        };


        player.NumberOfLoops = 0;
        System.Diagnostics.Debug.WriteLine("Start Playing");
        player.Play();

        return tcs.Task;
    }

application output