Timer in Xamarin.Forms
Take a look at Device class in Xamarin.Forms
and particularly at StartTimer
method.
Given that, you can setup your timer :
Device.StartTimer(TimeSpan.FromMilliseconds(300.0), TimerElapsed);
private bool TimerElapsed()
{
Device.BeginInvokeOnMainThread(() =>
{
//put here your code which updates the view
});
//return true to keep timer reccurring
//return false to stop timer
}
It will fire approximately every 300 milliseconds (depending on the device capabilities)
Regarding your code, you can start with something like that:
1.Add following to your play command :
Device.StartTimer(TimeSpan.FromSeconds(1.0), CheckPositionAndUpdateSlider);
2.Add CheckPositionAndUpdateSlider
method :
private bool CheckPositionAndUpdateSlider()
{
var position = DependencyService.Get<IAudio>().GetCurrentPosition();
Device.BeginInvokeOnMainThread(() =>
{
slider.Value = position;
});
return true;
}
Arti
Updated on June 04, 2022Comments
-
Arti about 2 years
I want to build my own audio player (as there no plugins available). I have used a slider to show progress of the player. I could allow user to go to specific location when the slider is moved but I can not synchronize it with the recording being played.
Form
int i = 1; Button btnPlay = new Button { Text = "Play/Pause", Command = new Command(() => { DependencyService.Get<IAudio>().PlayMp3File(); TimeSpan tmspan = new TimeSpan(00, 00, 00); label.Text = String.Format("{0:hh\\:mm\\:ss}", tmspan.Add(TimeSpan.FromMilliseconds(i))); i++; return true; }) }; 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) };
Service
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);//TimeSpan.FromMilliseconds(arr).TotalMinutes; } } }
Anyone has any idea on how to go about it?
On play the timer should start and also my slider value should increment. On pause the timer and slider should be paused and on stop it should be stopped.
-
Arti about 8 yearsIs there a way to pause or stop the timer?
-
Arkadiusz K about 8 yearsJust return
false
fromTimerElapsed
method in order to stop it. When you want to pause timer then you have to write this logic on your own. I mean stop the timer and then start timer again when you want to resume it. -
Arti about 8 yearsI cannot get my slider to move as per the recording progress. Any idea on that?
-
Arkadiusz K about 8 yearsDid you tested whether your timer is fired at all? I can't see your timer code, but maybe you forgot to notify about property changed for Slider?
-
Arti about 8 yearsOn click of play button I would like to start a timer (which is working-displayed in Label) also start my slider ( ie. move slider value as per the recording.) Getting my slider to move as recording proceed does't work.
-
Arkadiusz K about 8 yearsIn code in your question there isn't any code which starts timer and anything which after that updates slider value. I've edited my answer to include example how you can add code which will update slider.
-
Arti about 8 yearsDoesn't work. It seems to be blocking the UI and also the recording
-
Arkadiusz K about 8 yearsLet us continue this discussion in chat.
-
mr5 over 4 yearsDown side of this is that you can't use this without calling
Xamarin.Forms.Init()
which would be hassle if you're using this in a background service. -
c-sharp-and-swiftui-devni over 2 yearsU dont show what TimerElapsed should be ?