I have a piece of code at which when a timer runs out, a sound is played. This is done through this package Plugin.SimpleAudioPlayer
. This is portrayed by the PlaySound
function. The issue is when it reaches the end of the timer and tries to play the sound I get thie error on var player
(check code below): System.NotImplementedException: 'This functionality is not implemented in the .NET standard version of this assembly. Reference the NuGet package from your platform-specific (head) application project in order to reference the platform-specific implementation.'
. If there are better ways to achieve this please let me know.
Code:
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Microsoft.Maui.Controls;
using Plugin.SimpleAudioPlayer;
namespace CookOff.Models
{
public class Step : INotifyPropertyChanged
{
private bool isSelected;
private TimeSpan timer;
private bool isTimerRunning;
private bool isTimerPaused;
private TimeSpan originalTimer;
public int RecipeID { get; set; }
public string Description { get; set; }
public bool TimerRequired { get; set; }
public TimeSpan Timer
{
get => timer;
set
{
timer = value;
OnPropertyChanged();
}
}
public bool IsSelected
{
get => isSelected;
set
{
isSelected = value;
OnPropertyChanged();
}
}
public ICommand StartTimerCommand { get; }
public ICommand PauseTimerCommand { get; }
public ICommand StopTimerCommand { get; }
public Step()
{
StartTimerCommand = new Command(StartTimer);
PauseTimerCommand = new Command(PauseTimer);
StopTimerCommand = new Command(StopTimer);
}
public Step(int recipeID, string description, bool timerRequired, TimeSpan timer)
{
RecipeID = recipeID;
Description = description;
TimerRequired = timerRequired;
Timer = timer;
StartTimerCommand = new Command(StartTimer);
PauseTimerCommand = new Command(PauseTimer);
StopTimerCommand = new Command(StopTimer);
}
private void StartTimer()
{
if (!isTimerRunning || isTimerPaused)
{
isTimerRunning = true;
isTimerPaused = false;
originalTimer = Timer;
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
if (!isTimerRunning)
return false;
Timer = Timer.Subtract(TimeSpan.FromSeconds(1));
if (Timer <= TimeSpan.Zero)
{
Timer = TimeSpan.Zero;
isTimerRunning = false;
// PLAY SOUND WHEN TIMER RUNS OUT
PlaySound();
}
return isTimerRunning;
});
}
}
private void PauseTimer()
{
isTimerPaused = true;
isTimerRunning = false;
}
private void StopTimer()
{
isTimerRunning = false;
isTimerPaused = false;
Timer = originalTimer;
}
private void PlaySound() //ISSUE HERE
{
var player = CrossSimpleAudioPlayer.Current;
player.Load("Resources/Raw/timer_end.mp3");
player.Play();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
UPDATE FIXED:
Thanks Jason for the tip to use Plugin.Maui.Audio
. I have used the straighforward implementation as on their GitHub.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Microsoft.Maui.Controls;
using Plugin.Maui.Audio;
namespace CookOff.Models
{
public class Step : INotifyPropertyChanged
{
private bool isSelected;
private TimeSpan timer;
private bool isTimerRunning;
private bool isTimerPaused;
private TimeSpan originalTimer;
public int RecipeID { get; set; }
public string Description { get; set; }
public bool TimerRequired { get; set; }
public TimeSpan Timer
{
get => timer;
set
{
timer = value;
OnPropertyChanged();
}
}
public bool IsSelected
{
get => isSelected;
set
{
isSelected = value;
OnPropertyChanged();
}
}
public ICommand StartTimerCommand { get; }
public ICommand PauseTimerCommand { get; }
public ICommand StopTimerCommand { get; }
public Step()
{
StartTimerCommand = new Command(StartTimer);
PauseTimerCommand = new Command(PauseTimer);
StopTimerCommand = new Command(StopTimer);
}
public Step(int recipeID, string description, bool timerRequired, TimeSpan timer)
{
RecipeID = recipeID;
Description = description;
TimerRequired = timerRequired;
Timer = timer;
StartTimerCommand = new Command(StartTimer);
PauseTimerCommand = new Command(PauseTimer);
StopTimerCommand = new Command(StopTimer);
}
private void StartTimer()
{
if (!isTimerRunning || isTimerPaused)
{
isTimerRunning = true;
isTimerPaused = false;
originalTimer = Timer; // Store the original time when the timer starts
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
if (!isTimerRunning)
return false;
Timer = Timer.Subtract(TimeSpan.FromSeconds(1));
if (Timer <= TimeSpan.Zero)
{
Timer = TimeSpan.Zero;
isTimerRunning = false;
// Play sound
PlaySound();
}
return isTimerRunning;
});
}
}
private void PauseTimer()
{
isTimerPaused = true;
isTimerRunning = false;
}
private void StopTimer()
{
isTimerRunning = false;
isTimerPaused = false;
Timer = originalTimer;
}
private async void PlaySound()
{
try
{
Debug.WriteLine("Attempting to play sound in PlaySound method");
// STRAIGHTFORWARD AUDIO PLAYER
var audioPlayer = AudioManager.Current.CreatePlayer(await FileSystem.OpenAppPackageFileAsync("Resources/Raw/timer_end.mp3"));
if (audioPlayer == null)
{
Debug.WriteLine("AudioPlayer creation failed");
return;
}
audioPlayer.Play();
Debug.WriteLine("Sound played");
}
catch (Exception ex)
{
Debug.WriteLine($"Exception in PlaySound method: {ex.Message}");
Debug.WriteLine(ex.StackTrace);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
UPDATE FIXED:
Thanks Jason for the tip to use Plugin.Maui.Audio
. I have used the straighforward implementation as on their GitHub.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using Microsoft.Maui.Controls;
using Plugin.Maui.Audio;
namespace CookOff.Models
{
public class Step : INotifyPropertyChanged
{
private bool isSelected;
private TimeSpan timer;
private bool isTimerRunning;
private bool isTimerPaused;
private TimeSpan originalTimer;
public int RecipeID { get; set; }
public string Description { get; set; }
public bool TimerRequired { get; set; }
public TimeSpan Timer
{
get => timer;
set
{
timer = value;
OnPropertyChanged();
}
}
public bool IsSelected
{
get => isSelected;
set
{
isSelected = value;
OnPropertyChanged();
}
}
public ICommand StartTimerCommand { get; }
public ICommand PauseTimerCommand { get; }
public ICommand StopTimerCommand { get; }
public Step()
{
StartTimerCommand = new Command(StartTimer);
PauseTimerCommand = new Command(PauseTimer);
StopTimerCommand = new Command(StopTimer);
}
public Step(int recipeID, string description, bool timerRequired, TimeSpan timer)
{
RecipeID = recipeID;
Description = description;
TimerRequired = timerRequired;
Timer = timer;
StartTimerCommand = new Command(StartTimer);
PauseTimerCommand = new Command(PauseTimer);
StopTimerCommand = new Command(StopTimer);
}
private void StartTimer()
{
if (!isTimerRunning || isTimerPaused)
{
isTimerRunning = true;
isTimerPaused = false;
originalTimer = Timer; // Store the original time when the timer starts
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
if (!isTimerRunning)
return false;
Timer = Timer.Subtract(TimeSpan.FromSeconds(1));
if (Timer <= TimeSpan.Zero)
{
Timer = TimeSpan.Zero;
isTimerRunning = false;
// Play sound
PlaySound();
}
return isTimerRunning;
});
}
}
private void PauseTimer()
{
isTimerPaused = true;
isTimerRunning = false;
}
private void StopTimer()
{
isTimerRunning = false;
isTimerPaused = false;
Timer = originalTimer;
}
private async void PlaySound()
{
try
{
Debug.WriteLine("Attempting to play sound in PlaySound method");
// STRAIGHTFORWARD AUDIO PLAYER
var audioPlayer = AudioManager.Current.CreatePlayer(await FileSystem.OpenAppPackageFileAsync("Resources/Raw/timer_end.mp3"));
if (audioPlayer == null)
{
Debug.WriteLine("AudioPlayer creation failed");
return;
}
audioPlayer.Play();
Debug.WriteLine("Sound played");
}
catch (Exception ex)
{
Debug.WriteLine($"Exception in PlaySound method: {ex.Message}");
Debug.WriteLine(ex.StackTrace);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}