Last active
October 30, 2020 23:05
-
-
Save Ruffo324/f998c38ceff27c1eaebe5b489188c66d to your computer and use it in GitHub Desktop.
AfLooper - Simple 'afplay' wrapper with looping function for .NET Core
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.Threading; | |
using System.Threading.Tasks; | |
public class AfLooper | |
{ | |
// Value between 0 - 100. | |
public decimal Volume | |
{ | |
get => _volume; | |
set | |
{ | |
if (value == Volume) return; | |
_volume = value; | |
UpdateAfPlayArgs(); | |
} | |
} | |
public string FilePath | |
{ | |
get => _filePath; | |
set | |
{ | |
if (value == FilePath) return; | |
_filePath = value; | |
UpdateAfPlayArgs(); | |
} | |
} | |
public bool Loop | |
{ | |
get => _loop; | |
set | |
{ | |
if (value == Loop) return; | |
_loop = value; | |
} | |
} | |
private CancellationTokenSource _cancellation = new CancellationTokenSource(); | |
private string _filePath; | |
private decimal _volume; | |
private readonly ProcessStartInfo _processInfo = new ProcessStartInfo | |
{ | |
FileName = "afplay", | |
ErrorDialog = false, | |
UseShellExecute = true | |
}; | |
private Process _process; | |
private bool _loop; | |
public bool IsRunning => !_cancellation.IsCancellationRequested; | |
public AfLooper(string filePath, decimal volume = 50, bool loop = true) | |
{ | |
_filePath = filePath ?? throw new ArgumentNullException(nameof(filePath)); | |
_volume = volume; | |
_loop = loop; | |
UpdateAfPlayArgs(); | |
} | |
private void UpdateAfPlayArgs() | |
{ | |
_processInfo.Arguments = $"-v {_volume / 100:F3} '{_filePath}'"; | |
if (IsRunning) | |
ReStart(); | |
} | |
public void ReStart() => Start(); | |
public void Start() | |
{ | |
Stop(); | |
_cancellation = new CancellationTokenSource(); | |
new Task(() => | |
{ | |
while (!_cancellation.IsCancellationRequested) | |
try | |
{ | |
_process = Process.Start(_processInfo); | |
_process?.WaitForExit(); | |
if (!_loop) | |
Stop(); | |
} | |
catch (Exception) | |
{ | |
// ignored. | |
} | |
}).Start(); | |
} | |
/// <summary> | |
/// Forces the current playback to stop immediately. | |
/// </summary> | |
public void Stop() | |
{ | |
_cancellation?.Cancel(); | |
if (_process is Process p && !p.HasExited) | |
p.Kill(); | |
} | |
/// <summary> | |
/// Just stops repeating the audio file, | |
/// and waits until 'afplay' is done with the playback. | |
/// </summary> | |
public void SoftStop() | |
{ | |
_cancellation?.Cancel(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading.Tasks; | |
namespace ConsolePlayground | |
{ | |
// Example class | |
internal static class MainClass | |
{ | |
public static async Task Main(string[] args) | |
{ | |
var frog = @"/System/Library/Sounds/Frog.aiff"; | |
var submarine = @"/System/Library/Sounds/Submarine.aiff"; | |
var purr = @"/System/Library/Sounds/Purr.aiff"; | |
var audioPlayer = new AfLooper(purr, 10); | |
// Loop disabled play. | |
audioPlayer.Loop = true; | |
audioPlayer.Start(); | |
await Task.Delay(TimeSpan.FromSeconds(2)); | |
// Re-enabled looping play. | |
audioPlayer.Loop = false; | |
audioPlayer.Start(); | |
// Stop Start test. | |
await Task.Delay(TimeSpan.FromSeconds(2)); | |
audioPlayer.Stop(); | |
await Task.Delay(TimeSpan.FromSeconds(2)); | |
audioPlayer.Start(); | |
// Change file runtime test. | |
await Task.Delay(TimeSpan.FromSeconds(2)); | |
audioPlayer.FilePath = submarine; | |
await Task.Delay(TimeSpan.FromSeconds(2)); | |
audioPlayer.FilePath = frog; | |
await Task.Delay(TimeSpan.FromSeconds(2)); | |
audioPlayer.SoftStop(); | |
audioPlayer.FilePath = purr; | |
await Task.Delay(TimeSpan.FromSeconds(2)); | |
audioPlayer.Start(); | |
// change volume up, and down after. | |
for (var i = 0; i < 100; i++) | |
{ | |
audioPlayer.Volume = i; | |
await Task.Delay(TimeSpan.FromMilliseconds(50)); | |
} | |
for (var i = 100 - 1; i >= 0; i--) | |
{ | |
audioPlayer.Volume = i; | |
await Task.Delay(TimeSpan.FromMilliseconds(50)); | |
} | |
audioPlayer.SoftStop(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment