CefSharp detect webm video end - c#

I have a WPF C# application using cefsharp v79.1.360.
The app is happily playing a single local webm file inside the browser.
Now I would like to pass a string of local file names to the app and play them sequentially. Thus when one webm finishes playing the next one in sequence will start. Nothing else is contained in the page, just the webm.
My first thought was to detect when the current webm finishes and then load the next file. I am not seeing any events being thrown or handlers that can do this for me.
I am using the FrameLoadEnd handler for other purposes but it only fires when the webm has finished loading, not when it is done playing.
Anyone know if detecting the ending of a webm video is possible?
My other thought is to load each webm into a stream and play the entire batch.
For user experience purposes I think it would be better to play each one individually, in sequence.
Thanks

Decided the best way to solve the problem was to create an html page that would accept a delimited string of video locations. It handles cycling through the list, playing each one individually. All it had to do was change the src of the video tag when the onended event fired and when the loadPlaylist function below is called.
The C# app passed the playlist to the html via a javascript call:
Browser.FrameLoadEnd += (sender, args) =>
{
//Wait for the Main Frame to finish loading
if (args.Frame.IsMain)
{
var playlist = navigationContext.Parameters[NavigationParameterKeys.WebAddress].ToString();
args.Frame.ExecuteJavaScriptAsync("loadPlaylist('" + playlist +"');");
}
};

Related

Is there a way to make multiple running threads pulling data from a stream start writing that data to separate files at the exact same time?

I'm writing softare that records data from a number of sensors. A user should be able to press a button to start streaming and then another to start recording this data to a file. Each device has its own thread so pressing the stream button will start a thread to stream for each device, and pressing record should make all these threads start writing to files.
I've attempted to implement this by creating a new thread to start pulling samples and then using a volatile bool to tell the threads when to start writing the samples to a file.
Here is the code running inside the threads:
public void streamData(CancellationToken ct, liblsl.StreamInlet inlet)
{
while (true)
{
ct.ThrowIfCancellationRequested();
pullSampleFromLSL(inlet);
//start writing to file if requested
//if(_isRecording){
// writeToFile()
//}
}
}
This method hasn't provided the accuracy I was hoping for as each file records a different timestamp for when recording was started (recorded using Stopwatch.ElapsedMilliseconds from a set starting point). Is there a way to do this so that all the files begin at (as close to as possible) the exact same timestamp?
cheers
Actually I would use a monitor class that trought condition variables notify all thread to start.

Clicking a button then playing a sound, pauses the UI and if you spam the button continuously plays? [duplicate]

This question already has answers here:
How to use System.Media.SoundPlayer to asynchronously play a sound file?
(2 answers)
Closed 5 years ago.
I've been trying to get this button to do what I want for a little now. I want it to play a sound when I press it, which is what I managed to do. However, its like the application freezes every time you press the button, giving the sound all of its attention, etc. So basically my goal is to make the button play a sound without making the UI have to stop and allow it to play, before moving on. I also would like to know if there is a way to make a button play sound when pressed, but when pressed again the current sound is stopped and plays again, to prevent it from playing "X" amount of clicks you clicked the button, etc.
Here is my code:
public static void ButtonSound()
{
SoundPlayer _sound = new SoundPlayer();
try
{
_sound.Stop();
_sound.SoundLocation = path + "ButtonTap.wav";
_sound.Load();
_sound.PlaySync();
}
catch
{
}
finally
{
_sound.Dispose();
}
}
And Button code:
private void Button()
{
SoundPlayers.ButtonSound();
}
Note, I have my SoundPlayer in another class, and I am using DelegateCommands to reference my Button() method, etc. I am also using .wav files. Also, is there a more efficient way to achieve that task I am trying to accomplish? If you need anything else, just ask.
Thanks!
Your UI is freezing because that is what you are asking for when you call _sound.PlaySync().
Looking at the SoundPlayer documentation, you could use the Play() method:
Plays the .wav file using a new thread, and loads the .wav file first
if it has not been loaded.
Using this method should also solve the problem of playing the sound repeatedly, since you will no longer be queuing your calls.
Also, what you did there with Try-Finally-Dispose can be simplified with using, so your code would look like this:
public static void ButtonSound()
{
using (var _sound = new SoundPlayer())
{
_sound.SoundLocation = path + "ButtonTap.wav";
_sound.Play();
}
}
Note that your _sound.Stop() doesn't make sense, since you are calling it on a new object, but just calling Play() on a new object will make the old sound stop and then play the new one.
Also, the doc says that Play() loads the file if it has not been loaded, that is why I skipped the _sound.Load() call.

Proper usage for MvxFileDownloadCache.Clear

I'm trying to cleanup unwanted http image data that I have loaded via MvxImageViewLoader.
I've found the function clear in the FileDownloadCache which seems to do what I need.
var downloadCache = Mvx.Resolve<IMvxFileDownloadCache>();
downloadCache.Clear(_imageChart1ViewLoader.ImageUrl);
Periodically it calls a function (once a second by the looks of it) which deletes the files in the private list
private readonly List<string> _toDeleteFiles = new List<string>();
Clear adds the image by url to that list.
Except once I call this function I'm still able to see the image. I.e. it stays in memory.
So really I need to know where is a good place to be calling Clear and am I using it in the correct way. Currently I call it every time I exit my DetailView which downloads an image from a URL.
MvvmCross v4.2.2 (latest)

How do I read a file in parts with NAudio?

I am fairly new to C# and Mark's library NAudio. So I've tried learning by myself and I've come up with an basic audio player. But I have a problem.
When trying to load big files in the player the app freezes for 2-10 seconds while loading the entire file (I suppose). This is my code for reading the file:
if (target.EndsWith("mp3") || target.EndsWith("Mp3") || target.EndsWith("MP3"))
{
NAudio.Wave.WaveStream pcm = NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(new NAudio.Wave.Mp3FileReader(target));
stream = new NAudio.Wave.BlockAlignReductionStream(pcm);
}
All I really want is to read the file in parts. Like a buffer. Read 10 seconds from the HDD to RAM memory, then after those 10 seconds run out, read the next 10 seconds, and so on. I think this should resolve the freeze issue I have with large files.
The cause of the delay is that Mp3FileReader creates a table of contents to allow it to determine the file length and to enable quicker repositioning. You could try using MediaFoundationReader instead which would be quicker, but won't work on Windows XP.
all programs have delay to load big files. this is depended to client computer speed.
but you can use backgroundWorker in your program and show a loading animation on your application Form during the file loading.
add backgroundWorker tool on your form
use this code on open button click:
backgroundWorker_name.RunWorkerAsync();
and put your code to the DoWork event
private void backgroundWorker_name_DoWork(object sender, DoWorkEventArgs e)
{
}

SoundPlayer does not play sound first time it´s called

I've a really simple method for playing sound effects:
private void PlaySound(string file)
{
var sp = new SoundPlayer(#"Effects\" + file + ".wav");
sp.Play();
}
Then I do this to call it:
PlaySound("music");
Now, the first time PlaySound("music") gets called, it won't play it. The second time and all the other times after that it will.
Any ideas of what goes wrong here?
Try this:
private void PlaySound(string file){
using (SoundPlayer player = new SoundPlayer(#"Effects\" + file ' ".wav"))
{
// Use PlaySync to load and then play the sound.
player.PlaySync();
}
}
Why use PlaySync? If you just call the Play method in this program, the program will terminate before the sound plays. The Sync indicates that the program should pause while the sound plays.
You need to call the load method before playing.If the the file is not already loaded ,the file will be loaded with a call to Play.Which explains why the file is not played the first time.
If you call Play before the .wav file has been loaded into memory, the .wav file will be loaded before playback starts.-MSDN
Both Load and PlaySync will block the current thread.A better option would be to use the LoadAsync to load the file asynchronously.

Categories