Last active
May 27, 2021 21:33
-
-
Save StephenHodgson/d73d1fd351b5748c93b76af9245aa647 to your computer and use it in GitHub Desktop.
Test recording microphone data using LibVLCSharp
This file contains 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.IO; | |
using LibVLCSharp.Shared; | |
namespace test_microphone_recording | |
{ | |
internal class Program | |
{ | |
private static MemoryStream stream; | |
private static LibVLC vlc; | |
private static string AudioFormat = "S16N"; | |
private static uint Channels = 2; | |
private static uint SampleRate = 44100; | |
private static MediaPlayer mediaPlayer; | |
private static void Main(string[] _) | |
{ | |
Core.Initialize(); | |
vlc = new LibVLC("--no-video", "--no-sout-video"); | |
//vlc.Log += (_, _) => { }; | |
var media = new Media(vlc, "dshow://", FromType.FromLocation, ":no-video", ":dshow-vdev=none", ":dshow-adev="); | |
mediaPlayer = new MediaPlayer(media); | |
mediaPlayer.SetAudioFormatCallback(AudioSetup, AudioCleanup); | |
mediaPlayer.SetAudioCallbacks(PlayAudio, PauseAudio, ResumeAudio, FlushAudio, DrainAudio); | |
mediaPlayer.SetAudioFormat(AudioFormat, SampleRate, Channels); | |
Console.WriteLine("Press 'Esc' to quit. Press any other key to pause/play."); | |
Console.WriteLine(nameof(PlayAudio)); | |
mediaPlayer.Play(); | |
while (true) | |
{ | |
if (Console.ReadKey(true).Key == ConsoleKey.Escape) | |
{ | |
break; | |
} | |
if (!mediaPlayer.IsPlaying) | |
{ | |
Console.WriteLine(nameof(PlayAudio)); | |
mediaPlayer.Play(); | |
} | |
else | |
{ | |
mediaPlayer.Pause(); | |
} | |
} | |
} | |
private static unsafe void PlayAudio(IntPtr data, IntPtr samples, uint count, long pts) | |
{ | |
var bytes = new ReadOnlySpan<byte>(samples.ToPointer(), (int)(count * sizeof(float))); | |
stream.Write(bytes); | |
} | |
private static int AudioSetup(ref IntPtr opaque, ref IntPtr format, ref uint rate, ref uint channels) | |
{ | |
Channels = channels; | |
string formatString; | |
unsafe | |
{ | |
fixed (void* formatPtr = &format) | |
{ | |
formatString = new string((sbyte*)formatPtr); | |
} | |
} | |
Console.WriteLine($"{nameof(AudioSetup)} | format: {formatString} | channels:{channels} | rate: {rate}"); | |
stream = new MemoryStream(); | |
return 0; | |
} | |
private static void DrainAudio(IntPtr data) | |
{ | |
Console.WriteLine(nameof(DrainAudio)); | |
stream.Flush(); | |
} | |
private static void FlushAudio(IntPtr data, long pts) | |
{ | |
Console.WriteLine(nameof(FlushAudio)); | |
stream.Flush(); | |
} | |
private static void ResumeAudio(IntPtr data, long pts) | |
{ | |
Console.WriteLine(nameof(ResumeAudio)); | |
stream.SetLength(0); | |
} | |
private static void PauseAudio(IntPtr data, long pts) | |
{ | |
Console.WriteLine(nameof(PauseAudio)); | |
var streamMediaInput = new StreamMediaInput(stream); | |
var media = new Media(vlc, streamMediaInput, ":imem-cat 1", ":demux=rawaud"); | |
var playbackPlayer = new MediaPlayer(media); | |
playbackPlayer.SetAudioFormat(AudioFormat, SampleRate, Channels); | |
playbackPlayer.Play(media); | |
playbackPlayer.Stopped += Cleanup; | |
playbackPlayer.EndReached += Cleanup; | |
void Cleanup(object _, EventArgs __) | |
{ | |
Console.WriteLine(nameof(Cleanup)); | |
playbackPlayer.Dispose(); | |
playbackPlayer = null; | |
media.Dispose(); | |
streamMediaInput.Dispose(); | |
} | |
} | |
private static void AudioCleanup(IntPtr opaque) | |
{ | |
Console.WriteLine(nameof(AudioCleanup)); | |
stream.Dispose(); | |
stream = null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment