Xamarin.forms滑块为音频播放器栏

时间:2016-05-13 04:46:24

标签: c# xamarin.forms

我想使用xamarin.forms的滑块控件作为音频播放器栏。我有一个依赖服务来播放录音并获得总持续时间和当前位置。如何将其设置为我的滑块?

她是我的代码:

Button btnPlay = new Button
{
    Text = "Play/Pause",
    Command = new Command(() =>
                    {
                        DependencyService.Get<IAudio>().PlayMp3File();
                    })
};
Button btnStop = new Button { Text = "Stop" };
TimeSpan timeSpan = DependencyService.Get<IAudio>().GetInfo();
Label lblDuration = new Label { Text = String.Format("{0:hh\\:mm\\:ss}", timeSpan) };

var slider = new Slider {
    Minimum = 0,
    Maximum = timeSpan.TotalHours,
};
var label = new Label {
    Text = "Slider value is 0",
    FontSize = 25,
    HorizontalOptions = LayoutOptions.Start,
};
slider.ValueChanged += 
    (sender, e) => 
    {
        label.Text = String.Format("Slider value is {0:hh\\:mm\\:ss}", TimeSpan.FromMilliseconds(e.NewValue));
        DependencyService.Get<IAudio>().SeekTo(Convert.ToInt32(e.NewValue));

    };
MainPage = new ContentPage
{
    Content = new StackLayout {
        Children = {
            btnPlay,
            btnStop,
            slider,
            lblDuration,
            label
        }
    },  
    Padding = new Thickness (10, Device.OnPlatform (20, 0, 0), 10, 5)
};

我在标签中设置总持续时间。如何对更改滑块进行编程以将标签设置为当前位置。我的滑块值将如何根据播放的文件递增?

修改

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AudioTest
{
    public interface IAudio
    {
        Task PlayMp3File();
       // bool PlayWavFile(string fileName);

        Task SeekTo(int msec);
        TimeSpan GetInfo();

        void Stop();
        double CurrentPosition();

        bool Isplaying();
    }
}

Audioservice.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AudioTest.Droid;
using Xamarin.Forms;
using Android.Media;
using System.Threading.Tasks;


[assembly: Dependency(typeof(AudioService))]

namespace AudioTest.Droid
{

    public class AudioService : IAudio
    {
        public AudioService() { }

        MediaPlayer player = null;

        public async Task StartPlayerAsync()
        {
            try
            {
                if (player == null)
                {
                    player = new MediaPlayer();
                    player = MediaPlayer.Create(global::Android.App.Application.Context, Resource.Raw.test);
                    player.Start();
                }
                else
                {
                    if (player.IsPlaying == true)
                    {
                        player.Pause();
                    }
                    else
                    {
                        player.Start();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex.StackTrace);
            }
        }

        public void StopPlayer()
        {
            if ((player != null))
            {
                if (player.IsPlaying)
                {
                    player.Stop();
                }
                player.Release();
                player = null;
            }
        }

        public async Task PlayMp3File()
        {
            await StartPlayerAsync();
        }

        public void Stop()
        {
            this.StopPlayer();
        }

        public async Task SeekTo( int s)
        {
            await seekTo(s);
        }

        public double CurrentPosition()
        {
            if ((player != null))
            {
                return player.CurrentPosition;
            }
            else
            { return 0; }
        }

        private async Task seekTo(int mseconds)
        {
            if (player == null)
            {
                player = new MediaPlayer();
                player = MediaPlayer.Create(global::Android.App.Application.Context, Resource.Raw.test);

            }

            player.SeekTo(mseconds);
            player.Start();
        }



        public TimeSpan GetInfo()
        {
            int arr;
            if (player == null)
            {
                player = new MediaPlayer();
                player = MediaPlayer.Create(global::Android.App.Application.Context, Resource.Raw.test);

            }
            arr = player.Duration;

            return TimeSpan.FromMilliseconds(arr);
        }


       public bool Isplaying()
        {
            if (player == null)
            {
                return false;


            }
            else { 
            return player.IsPlaying;
                }

        }
    }
}

1 个答案:

答案 0 :(得分:1)

在我回答这个问题之前,让我问你一个问题:你真的想让滑块追踪时间吗?我希望媒体滑块可以跟踪秒或十分之一秒;小时是一个非常艰难的步骤。

假设您是IAudio接口及其实现的作者,我的建议是IAudio接口公开并触发事件(例如:PositionChanged)每当播放位置改变时包括当前位置。 IAudio接口的实现超出了这个问题的范围,但我希望您订阅一个事件或使用您正在使用的任何媒体堆栈注册一个回调,那就是反过来发起PositionChanged事件。

注意:我也假设你真的意味着秒;如果你真的是DID意味着小时,请将以下位置更改为小时。

public class PositionChangedEventArgs : EventArgs
{
    public PositionChangedEventArgs(int seconds)
    {
        Seconds = seconds;
    }

    public int Seconds { get; set; }
}

public interface IAudio
{
    ...
    event EventHandler<PositionChangedEventArgs> PositionChanged;
}

然后,在PositionChanged的事件处理程序中,您将更新滑块的位置:

// note that we're caching our reference to IAudio;
// I don't know whether it's a singleton or not
var audioService = DependencyService.Get<IAudio>(); 
TimeSpan timeSpan = audioService.GetInfo();
Label lblDuration = new Label { Text = String.Format("{0:hh\\:mm\\:ss}", timeSpan) };

var slider = new Slider {
    Minimum = 0,
    Maximum = timeSpan.TotalSeconds,
};
audioService.PositionChanged += (s, e) => {
    slider.Value = e.Position;
    label.Text = String.Format("Slider value is {0}", e.Position);
}