I am using VideoLan.VLC to get 20 seconds of an audio stream every 30 seconds. I have a loop, something like
private LibVLC libvlc = new LibVLC();
private MediaPlayer mediaPlayer = null;
private Media Media = null;
private string AudioSampleFileName { get {
return "audio_" + DateTime.Now.ToString("yyyyMMdd_HHmmss")+
".ts";
} }
public void Start(){
mediaPlayer = new MediaPlayer(libvlc);
while(...){
Get_20_seconds_audio_sample();
Wait_30_Seconds();
}
}
public void Get_sample(Uri playPathUri, string FileName)
{
var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var destination = Path.Combine(currentDirectory, FileName);
var mediaOptions = new string[]
{
":sout=#file{dst=" + destination + ",channels=1,samplerate=16000}",
":sout-keep"
};
if (Media == null)
{
Media = new Media(libvlc, playPathUri, mediaOptions);
mediaPlayer.Media = Media;
}
else {
Media.AddOption(":sout=#file{dst=" + destination + ",channels=1,samplerate=16000}");
}
mediaPlayer.Play();
}
public void Get_20_seconds_audio_sample(){
Get_sample(RadioURI,AudioSampleFileName);
Wait_20_seconds();
Stop();
}
public void Stop()
{
mediaPlayer.Stop();
}
The Problem is that radio streming ususally starts with a commercial that lasts about 25 seconds. Every sample plays the commercial. It seems that Stop() closes the stream until Play() is called again and it restart the stream. I tired to pause the audio but, well...it makes no much sense to pause and play.
I can accept to get the commercial only in the first sample but then I want the regular radio audio. Is there a way not to close the stream every time? I am not tied to VideoLan dll so I can start from scratch if you have a better way to do it.
Use Audio callbacks and save the audio stream yourself. Full sample:
class Program
{
// This sample shows you how you can use SetAudioFormatCallback and SetAudioCallbacks. It does two things:
// 1) Play the sound from the specified video using NAudio
// 2) Extract the sound into a file using NAudio
static void Main(string[] args)
{
Core.Initialize();
using var libVLC = new LibVLC(enableDebugLogs: true);
using var media = new Media(libVLC,
new Uri("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4"),
":no-video");
using var mediaPlayer = new MediaPlayer(media);
using var outputDevice = new WaveOutEvent();
var waveFormat = new WaveFormat(8000, 16, 1);
var writer = new WaveFileWriter("sound.wav", waveFormat);
var waveProvider = new BufferedWaveProvider(waveFormat);
outputDevice.Init(waveProvider);
mediaPlayer.SetAudioFormatCallback(AudioSetup, AudioCleanup);
mediaPlayer.SetAudioCallbacks(PlayAudio, PauseAudio, ResumeAudio, FlushAudio, DrainAudio);
mediaPlayer.Play();
mediaPlayer.Time = 20_000; // Seek the video 20 seconds
outputDevice.Play();
Console.WriteLine("Press 'q' to quit. Press any other key to pause/play.");
while (true)
{
if (Console.ReadKey().KeyChar == 'q')
break;
if (mediaPlayer.IsPlaying)
mediaPlayer.Pause();
else
mediaPlayer.Play();
}
void PlayAudio(IntPtr data, IntPtr samples, uint count, long pts)
{
int bytes = (int)count * 2; // (16 bit, 1 channel)
var buffer = new byte[bytes];
Marshal.Copy(samples, buffer, 0, bytes);
waveProvider.AddSamples(buffer, 0, bytes);
writer.Write(buffer, 0, bytes);
}
int AudioSetup(ref IntPtr opaque, ref IntPtr format, ref uint rate, ref uint channels)
{
channels = (uint)waveFormat.Channels;
rate = (uint)waveFormat.SampleRate;
return 0;
}
void DrainAudio(IntPtr data)
{
writer.Flush();
}
void FlushAudio(IntPtr data, long pts)
{
writer.Flush();
waveProvider.ClearBuffer();
}
void ResumeAudio(IntPtr data, long pts)
{
outputDevice.Play();
}
void PauseAudio(IntPtr data, long pts)
{
outputDevice.Pause();
}
void AudioCleanup(IntPtr opaque) { }
}
}