简体   繁体   English

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

[英]Xamarin.forms slider as an Audio player bar

I would like to use slider control of xamarin.forms as an audio player bar. 我想将xamarin.forms的滑块控件用作音频播放器栏。 I have a dependency service to play the recording and get the total duration and current position. 我有一个依赖服务来播放记录并获取总持续时间和当前位置。 How will have to set it to my slider? 如何将其设置到我的滑块上?

Her is my code: 她是我的代码:

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

I am setting total duration in a label. 我正在标签中设置总持续时间。 How will I have to program on change slider to set label to current position . 我如何在更改滑块上编程才能将标签设置为当前位置 And how will my slider value will be incremented based on file played? 以及如何根据播放的文件增加滑块值

Edit 编辑

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

        }
    }
}

Before I answer the question, let me ask you one of my own: do you really want the slider to track hours? 在我回答问题之前,让我问一个我自己的问题:您是否真的希望滑块跟踪小时? I would expect a media slider to track seconds or tenths of seconds; 我希望媒体滑块能跟踪几秒或十分之一秒; hours is a very coarse step. 小时是非常艰难的一步。

Assuming that you are the author of the IAudio interface and its implementation, my recommendation would be for the IAudio interface to expose and fire an event (for example: PositionChanged ) that includes the current position whenever the playback position changes. 假设您是IAudio接口及其实现的作者,我的建议是IAudio接口公开并激发一个事件(例如: PositionChanged ),该事件将在播放位置更改时包含当前位置。 The implementation of the IAudio interface is beyond the scope of this question, but I would expect that you'd subscribe to an event or register a callback with whatever media stack you're using, and that would in turn fire the PositionChanged event. IAudio接口的实现超出了此问题的范围,但是我希望您订阅一个事件或使用您正在使用的任何媒体堆栈注册一个回调,这又将触发PositionChanged事件。

NOTE: I'm also assuming you really meant seconds; 注意:我还假设您的意思是秒。 if you really DID mean hours, change the below position to Hours. 如果您的实际DID是小时,请将以下位置更改为小时。

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

    public int Seconds { get; set; }
}

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

Then, in the event handler for PositionChanged, you would update the position of the slider: 然后,在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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM