Can't delete file after disposing AudioVideoPlayback.Video
.Net 2.0
C#
VS2005
SQL Server 2005
I am developing a Windows Forms training application using numerous avi files and AudioVideoPlayback.Video to play them.
The file names are stored in a SS2K5 database and the files themselves are encrypted using System.Security.Cryptology. I decrypt the file into a temporary file and play that file.
The problem I have is that I cannot delete the file until the application exits.
I have tried Video.Dispose() and it doesn't release the file lock.
The player is an MDI child form.
Any suggestions?
[595 byte] By [
DanEpps] at [2007-12-28]
Does nobody know how to delete a file that has been opened by AudioVideoPlayback.Video?
Dispose() is there to release any unmanaged objects, well that’s what I gather from the documentation. After you’ve finished with the video and disposed maybe you should null the video and condemn the managed object to the garbage collection. Create a method that you can call before loading and when you finish to perform the task, something like:
Video video = null;
void Cleanup()
{
if(video != null)
{
video.Stop(); // Stop playing
video.Dispose(); // Free unmanaged
video = null; // Garbage collect managed
// Free temp file if used
// …
}
}
void LoadVideo()
{
// Make sure we’re clean
Cleanup();
// Load the stuff up again
video = new Video(fname);
// …
}
I don’t really use managed DX so I could be barking up the wrong tree, in that case sorry.
Thanks for the reply. Unfortunately I am already doing what you suggest but the file just refuses to go away until the application exits.
This has something to do with AudioVideoPlayback as I can delete the file until I use it. Once it has been "touched" by the mannaged DX it cannot be deleted.
On a good note, I have been able to successfully overwrite the file during the same session so all is not lost.
That is odd. Do you actually dispose of the temporary file after use and then recreate it? Just out of interest.
Sort of...In the MDIParent form I do this:
FileStream
fout = new FileStream(outName, FileMode.Create, FileAccess.Write, FileShare.Delete);<code omitted for clarity>
CryptoStream
encStream = new CryptoStream(fout, des.CreateDecryptor(key, iv), CryptoStreamMode.Write);while (rdlen < totlen){
len = fin.Read(bin, 0, 8192);
encStream.Write(bin, 0, len);
rdlen = rdlen + len;
worker.ReportProgress(
Convert.ToInt32(rdlen));}
encStream.Close();
fout.Close();
This allows me to use the same file name for different avi content. I have tried using File.Delete in the MDIChild and MDIParent but neither will physically remove the file until the application exits.
I dispose of everything in the MDIChild before closing it and returning to the MDIParent.
I have resorted to performing the delete in the closing event of the MDIParent and just reusing the same file name for each new video in the same session. It works but is not exactly what I want. If the program crashes for any reason the unencrypted avi is left intact.
David Weller:
Why was my post marked as an answer? The question of WHY AudioVideoPlayBack does not release the file to be deleted has NOT been answered.
The code snippet supplied is what I have had in my program all along and IS NOT an answer!
That is confusing. I was going to suggest to try forcing garbage collection by using System.GC.Collect() on the objects generation which you can get with System.GC.GetGeneration(), but from what I gather you have an actual physical file there, very dodgy and not very safe.
Sorry for the confusion...by "temporary file" I mean that I am decrypting the avi into a transient physical file for playing (you can't play from a stream, a physical file is required) and deleting that file upon completion of playback.
The files are fairly large, averaging 300MB and represent hundreds of hours of work so I encrypt them to prevent piracy. In all there are more than 30 such files in the application.
I tried storing the files in a database but when they are loaded into the application from the database they cause an out of memory exception.
Thisng would be so much simpler if I could just use the stream output instead of a physical file.
If you really want to find out what the problem is then you’re going to have to do some experimenting because at the moment the pictures too big. Is it DX? FileStream? Crypto? SQL? Etc? Basically you’ll have to start eliminating each element from your list to find out which thing still has a hold over the file. Maybe like creating a simple app that just creates a file then tries to delete it and if it isn’t deleted what happens if you force a garbage collection? The thing about garbage collection is that it isn’t called every second or so, it’s called when memory is requested and generation 0 is full so if you have quite a bit of memory on your machine it might never be called till the end when the app exits. Then you can try filling the file with a bog standard avi file and go through the same process. Then see what happens with DX. And just continue up the ladder till you are where you are now. I know it’s a bit much but once you pinpoint the culprit you can actually do research on the subject, this might not be the right forum if it isn’t a DX thing. The thing is you have something working at the moment so you can take your time, think of it as a beta version until you perfect it.
Been there, done that, but I didn't buy the t-shirt. You and I seem to be thinking along the same lines on this
. That is exactly how I determined it to be DX that is not releasing the file lock.
This is a fairly complex application with all that is going on in it. It has text, slide show and video instruction. There are worksheets to print, pre-instruction knowledge assessments and post-instruction tests. In all the application and content will probably take about 12 CDs to publish.
I eliminated everything extraneous in the equation and used an unencrypted 1MB file for testing. I can do anything with the file, either in the MDIParent or Child, as long as I don't play it. I can delete it in the parent or child and it goes away immediately until it has been played.
Once the player touches the file it gets greedy and refuses to let it go.
You are correct in your approach and that is exactly what I am doing--treating this as a beta until I can determine how to better handle the file. It may be that I have to go with what I current have. At least it hasn't stopped development.
I still lament...if only I could play the file directly from the cryptostream...
I have the same problem. My application uses temp files to play movie files using DirectX AudioVideoPlayback. I cannot release the files after playing it. It seems like the movies are still active, even after calling dispose.
I have a function that cleans up after the movie player when the
application exits. Sometimes it deletes up to 50 files when it exits.
Also, the only way I could get the movie player to respond to mouse events (click to pause), was to use:
VidObj.Fullscreen = True
VidObj.Fullscreen = False
This makes it respond to mouse events. Nothing else works.
But, this causes new problems. If the movie is played on a secondary monitor, the primary display changes resolution, goes black, and after about 2 seconds it works fine.
There must be a better way to play video on .net.
Here is what I ended up doing:
I compiled the player as a stand-alone exe that deletes the file when it exits. Then from the main application I execute the player in a separate process using Process.Start.
I don't exactly like this solution but it works. The problem I have is that I have to use transient files and immediately delete them due to space considerations. Some of my videos approach 500MB and there are dozens of them. I have to keep them on CD then decrypt to hard disk for playing just to prevent installing 5 or 6GB on the user's hard disk.
If only the player could use input from the decryption stream (or any stream input) we wouldn't have to worry about transient files.
I'm still looking for a better way if anyone has one.
Thank you. I wanted to convert everything to C#.
But it seems I would have the exact same problems, only months later.
Do you know if Microsoft plans to update the Microsoft.DirectX.AudioVideoPlayback library?
It was never updated after version 1. Maybe they don't know about the bugs.
Just hoping here. =)
Your workaround will not work for me. I created a complete video player using the library, integrated with the rest of the application. I wont be able to get proper feedback from it.
What is the Microsoft way to play video inside an application from VB.Net or C#?
I cant find any control for video, included with Visual Studio 2005 Professional Edition.
I sure wish they would update it but I don't know of any plans to do so.
I think they would prefer us to use Media Player or, with .Net 3.0, WPF.
You can add the Media Player control to your application easily. I didn't want to use it because I wanted my own control set fro the player. With Media Player the user always has an option to save the currently loaded video as a file which defeats my purpose of encrypting the files. If you are not concerned with users saving copies of the files then Media Player is certainly the easiest to implement.