Audio disposing problems using AudioVideoPlayback library - c#

I'm trying to make playlist, where music plays one after another. I need to Dispose() Audio, when it finishes, because memory leak will occur. I wrote this code:
Audio a = new Audio(#"Music\Title.ogg");
a.Ending += new EventHandler((sender, e) => { (sender as Audio).Dispose(); });
a.Play();
The problem is that I have System.AccessViolationException in Application.Run(new MainForm());: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. It happens in ending event handler right after music finishes playing.
So, how can I play some music files one after another and dispose previous audio afer it finishes?

Don't dispose Audio inside it's own event because this class may want to do some bookkeeping work after invoking your handler.
I don't know logic of your applications but here are some idea, try to call Open on this object inside event handler. It should be smart enough to dispose old data and load new.

Related

Why I'm receiving Access Violation Exception when try to dispose VideoView in LibVLCSharp

I'm using Stylet as MVVM framework and LibVLCSharp.WPF 3.6.5 + VideoLAN.LibVLC.Windows 3.0.16 in my project for streaming camera rtsp streams.
VideoView is included in my VLCPLayer custom user control, and that control is exposed as a property in my view model. I don't know if this is a good thing, but in this way I managed to make some kind of custom full screen video with custom buttons.
Everything works fine until I try to close player, or better to say try to dispose VideoView.
I have something like this:
public void Dispose()
{
//these are custom events in my user control
VlcPlayer.ClosePlayer -= ClosePlayer;
VlcPlayer.RestorePlayer -= RestorePlayer;
VlcPlayer.MinimizePlayer -= MinimizePlayer;
//here I try to dispose player and VideoView
VlcPlayer.VideoView.MediaPlayer.Stop();
VlcPlayer.VideoView.MediaPlayer.Media.Dispose();
VlcPlayer.VideoView.MediaPlayer.Dispose();
//here I'm getting Access Violation Exception
VlcPlayer.VideoView.Dispose();
}
If I don't dispose VideoView it remains in memory and every time I start new stream new VideoView is added to memory, so if I opened and closed one stream and then opened the same or whatever stream, I'll have in memory 2 VideoViews instead of one. I have to release memory of unused VideoViews and players since application will be used for some kind of surveillance, so it will have lot of streams at the same time opened, and lot of VideoViews opened.
Here I found similar issue, but it was reportedly solved updating to newest version of LibVLCSharp, but my version is newer than from mentioned post and I still have similar problem.
I'd appreciate any kind of help on this issue. Thanks.

CefSharp detect webm video end

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 +"');");
}
};

How do you stop SoundEffect from crashing XNA windows games when they are closed?

I am creating a game for windows in xna using Visual C# Express. In the game, there are six SoundEffect objects which regularly have their Play() methods called. The problem is that sometimes when the game is closed it crashes. It appears to happen whenever the window is closed while a soundeffect is playing. This is the message which pops up in Visual C#:
AccessViolationException was unhandled
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
There isn't any source available in visual studio to debug and when the "get general help for this exception" is clicked, a blank page pops up..
The code used looks a lot like the MSDN example. This looks like a problem that exists somewhere in the underlying framework somewhere, not my code. But of course I don't know for sure. This has happened many times.
http://msdn.microsoft.com/en-us/library/bb195053.aspx
Here are the complete exception details:
System.AccessViolationException was unhandled
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=Microsoft.Xna.Framework
StackTrace:
at Microsoft.Xna.Framework.Audio.AudioCallbackDispatcher.IsEventRegistered(EventType type)
at Microsoft.Xna.Framework.Audio.AudioCallbackDispatcher.UnregisterEvent(EventType type)
at Microsoft.Xna.Framework.Audio.KernelMicrophone.ShutdownCaptureEngine()
at Microsoft.Xna.Framework.Audio.MicrophoneUnsafeNativeMethods.ShutdownCaptureEngine()
at Microsoft.Xna.Framework.Audio.AudioRendererShutdownHandler.AppExitingEventHandler(Object sender, EventArgs args)
InnerException:
(I also have music playing via MediaPlayer, but I don't think it's related.)
EDIT: I seem to have found something which works, but it's kind of hackish and really shouldn't be necessary. I'm still open to any more elegant solutions.
Call this line in Game1.UnloadContent(). It will make sure (if your sound effects are all shorter than 3 seconds) that no sound is playing when the program actually closes.
System.Threading.Thread.Sleep(3000);
Make the SoundEffect object a class member and call the SoundEffect's Dispose() method on class deconstruction:
class MyClass
{
~MyClass()
{
effect.Dispose();
}
SoundEffect effect;
}
This should let the SoundEffect object clean itself up when you close the game. You can read about objects that are Disposable here: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
Can you make MyClass implement IDisposable and dispose of the SoundEffect in that method?
I think it's pretty safe to say that this is a bug in the framework. Because it's in the audio code, perhaps the framework is not handling something it's getting from a driver correctly. It's hard to say for sure.
Suffice to say that an AccessViolationException coming out of the framework is not "normal". It's almost certainly not your fault.
The function IsEventRegistered that the exception occurs in is an unsafe function. So it's likely that function is doing exactly what the exception says: it is accessing an invalid memory address.
The exception is coming from the shutdown code for audio capture (microphone), so are you doing anything with the microphone in your code? You could possibly experiment with using/not using the microphone and see what happens.
Also: does this happen when you run without the debugger attached? (Ctrl+F5)
As for fixing the problem: Your solution is not a bad work-around.
If you cannot afford to wait the three seconds, and you want to get your hands dirty and write some very questionable (semi-unportable, not-necessaraly-forward-compatible) code: You could use reflection to access the private properties of the audio system. Find the list of SoundEffectInstance objects that are created internally whenever you call SoundEffect.Play, and then stop those instances before you shutdown.
Or you could do effectively the same thing by never calling Play, but instead calling CreateInstance and managing fire-and-forget sound effects on your own. The downside is that this requires writing an awful lot of code!
I had the same problem and I did nulls for my sound collections in class finalizer(destructor). Works for me.
public class Audio
{
private ContentManager content;
public List<SoundEffectInstance> SoundInstance { get; private set; }
public AudioEmitter Emitter { get; set; }
public AudioListener Listener { get; set; }
public List<SoundEffect> Sound { get; set; }
public Audio(ContentManager content)
{
this.content = content;
Emitter = new AudioEmitter();
Listener = new AudioListener();
Sound = new List<SoundEffect>();
SoundInstance = new List<SoundEffectInstance>();
}
//set to null your sound instances and effects :D
~Audio()
{
Sound = null;
SoundInstance = null;
}
...

Minimize lag when using System.Speech.Synthesis

I am playing with using TTS built into .NET 4 and want the speech to happen immediately, but am instead encountering a lag between when I call Speak and when I get the audio.
I am developing a simple count-down timer that calls off the last five seconds and completion (5... 4... 3... 2... 1... Done), but when the screen updates with the new time, the TTS lags behind, getting worse for every invocation. I tried using SpeakAsync, but this only made it worse. Currently, Speak is being called outside the UI thread (in the Timer Tick event handler).
Is there a way to minimize this lag, such as pre-computing the speech and caching it or creating some kind of special TTS thread?
I somehow read past the API call I needed at least a hundred times. I was looking for SpeechSynthesizer.SetOutputToWaveStream.
MemoryStream stream = new MemoryStream();
SpeechSynthesizer synth = new SpeechSynthesizer();
synth.SetOutputToWaveStream(stream);
synth.Play(text);
stream.Position = 0;
SoundPlayer player = new SoundPlayer(stream);
player.Play();
This code will use TTS to turn text into a WAV file that is streamed into stream. You need to reset the position of the MemoryStream so that when you create a SoundPlayer from it, it starts reading the stream from the beginning instead of the end. Once you have the SoundPlayer initialized, you can save it somewhere so you can play it later instantly instead of having to wait for the TTS to initialize and play the sound.

C# Error on Close

When I close my C# application, I am getting the a windows sound that indicates an error. However, when I debug through the close process, I get all the way back up into the Program class...
It gets past Application.Run(..), exits the static void Main() function, and then makes the error noise.
Other than the noise there is nothing indicative of an error. I don't even know where to begin looking! Any ideas?
One thing that you could to in order to maybe get some information is to hook up event listeners for the AppDomain.UnhandledException and Application.ThreadException events. It's a long shot, but may provide some info. You could add the following in the beginning of the Main function to set them up, and have them show any exception info in a message box:
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(delegate(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show(e.ExceptionObject.ToString());
});
Application.ThreadException += new ThreadExceptionEventHandler(delegate(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.ToString());
});
// run your app
}
It only happens when you close your app or does it happen when you close any app?
My first thought would be that someone changed your windows sound scheme and set the close program sound to mess with you :).
Something is going wrong in the cleanup, that could be very hard to find. There are two ways to attack this:
Enhance the chances of detecting it while you're still in control (in Main) by wrapping everything in your Main in a try/catch and add some code after the Application.Run to get as much of the cleanup going as possible. A few things I can think of:
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
Collect at least 2 times, maybe more. In the same spirit, add a few Application.DoEvents() in the OnClosing of the MainForm.
The other approach is more dependent on your code, to take a stab in the dark: look for all static fields/properties you can set to null and Disposable objects you can Dispose deterministically on Exit.
And all this in combination with Fredrik Mörks suggestion for the UnhandledException event.
Do you have any code that raises custom events? Could these processes still be running when the app tries to close in real-time?
Do you have any custom Dispose code that could be running at time of close?

Categories