I'm writing a program to show different pictures and videos on a form. I started with displaying images with transparency using GDI. Due to the fact that GDI doesn't support transparency, the loading and displaying was very very slow, so I moved over to SharpDX.
In the meantime I managed (with one of the samples from SharpDX) to display different images on my form with opacity, positioning and sizing the images.
The images are drawn with DrawBitmap of the RenderTarget class in the render loop.
Now I want to do the same with videos. My goal is to play videos (more than one at the same time) in my form and set the position, size and transparency of the different videos.
I'm new to SharpDX and information about graphic programming and the documentation and the samples of SharpDX are very rare. I found many samples for playing videos with SharpDX, but all for XAML and WIN8 or Store-Apps, but no samples of how to play video in normal C# programs. What I found is one video player with SharpDX, but I don't know how to change this sample to add transpareny, sizing and positioning of the video playing.
Can anyone give me some examples how to play videos with SharpDX in a form or picturebox/panel? It would be great if this would show the things from above.
Related
I have a C# application which uses DirectShow to show play video clips. We recently tried to play a video that is 9600x1080 px and it would not show. DirectShow emits events that everything.
We use K-Lite codec pack (1295) and utilise ffdshow libx264 as codec and video renderer. Media Player Classic using the same renderer can play the clip just fine. The latest version of our application use DirectShow.NET while the older versions call DirectShow interfaces directly. Both old and new versions of our application have the same issues.
After some experimentation we have found out the following:
If the video window width is 4096px or narrower it will render video. If it is 4097 or wider it will not render any video. We tried playing a HD-clip and a 720-clip with the same results. They will play when the video window is 4096x1080 but not when the window is 4097x1080 or wider.
When changing resolution or graphic settings there are some flashes (a few frames) of the video when the settings is applied, so that would suggest that it is in fact playing the video but it displays only black.
Tested on Windows 10, 64 bit.
Any ideas of what the we can do to fix this?
The essential part is the video renderer you are using. Even though you did not mention, it is likely that you just use the defaults and this is a VMR-7 in windowed mode. This gets you an aged legacy component with limitations you are hitting.
You are interested in updating your application to use EVR.
Choosing the Right Video Renderer
[…]
In Windows Vista and later, applications should use the EVR if the hardware supports it.
[…] methods use the VMR-7 by default. […] The EVR and VMR-9 are never the default renderers.
I found this article http://web.archive.org/web/20130820015012/http://madskristensen.net/post/Examine-animated-Gife28099s-in-C.aspx (very helpful).
Unfortunately, our favorite hobbled race horse, UWP, does not include the required APIs.
I am working on a slide show app and would like to allow the user to advance an image with a set timing, except if it is an animated GIF, then I want to show the full animation once...
So, where can I extract the duration of the complete GIF animation, using the UWP on board tools?
I'm being annoyed by an odd behavior of Interop.quartztypelib in making media player with c#. With the help this link
http://www.codeproject.com/Articles/2632/DirectShow-MediaPlayer-in-C?msg=4853463#xx4853463xx
I created my own video player with Interop.quartztypelib. There's an important function for me to implement is that my application shall be able to capture the video image, just like you click "ALT" + "Printscreen" to make a screenshot of an active window in windows. But surprisingly I found that in the image captured by my application (I use
Graphics.CopyFromScreen
in my code), there's no video image on the video screen! I got the image of my form (the video player) but not the image of the video being played! And clicking "ALT" + "Printscreen" just gives me the same result!
I'm wondering if this Interop.quartztypelib doesn't support image capture. Anybody knows if there's a way to do settings to enable this? Thanks.
Printscreen doesn't do that
You need to implement some way of switching out of overlay, or some other way of getting a still. There is some trick with hardware acceleration, buts its not really applicable to you as the application dev. You're probably have to get antiquated with rendering api's.
For OpenGL api I think it would be glReadPixels.
For directX here's a SO question. I'm going to guess its directX in your case.
I'm skeptical if I'm doing this the right way.
I have to play an animation at about 60fps. I'm using a List<Image> to load all the frames at the time of initialization. And then using a System.Timers.Timer to call an event at every 10ms which will change the image in the pictureBox.
List<Image> imageList = new List<Image>();
private static Timer_Event(o, e)
{
pictureBox.Image = imageList[i++];
}
So, am I doing this right? Is there a better approach?
What you're describing seems unlikely to work in a robust fashion. Here's a brief summary:
In my experience, timers aren't generally accurate. Since timer messages go through the Windows Message pump, they can only move as fast as your Windows UI processes messages. Any application that interferes with messages will cause your timers to stutter, although careful work can prevent most of this. Some classic discussion of timers here: Winforms Timer for Dummies
In general, List is a very inefficient way to store images. For a one-second animation at 60 frames per second, you will have to hold 60 images in memory and decompress each one individually.
Here are some possible solutions, and the tradeoffs they entail:
Full Motion Video
If you are looking to present a full motion video on your form, you should really consider using a MediaElement (for WPF applications: http://www.c-sharpcorner.com/uploadfile/dpatra/media-element-in-wpf/ ) or a MediaPlayer object (for WinForms applications: http://msdn.microsoft.com/en-us/library/bb383953(v=vs.90).aspx ).
This will allow you to play a lengthy video that contains extremely high quality images, varied compression, and start or stop the playback arbitrarily. However, the startup and memory usage requirements of a full video player are greater than just displaying a single image on screen. You will find that your application takes a moment to initialize the video subsystem, which may be annoying.
Animated Images
It's possible to show an animated image in a picturebox in Windows Forms or WPF. You would simply generate the animated image - generally using a GIF animation file. This will work smoothly for a majority of simple animations, and it's possible to get free-to-use animated GIFs from websites like this one: http://www.chimply.com/Generator
Here's a walkthrough of how to place an animated GIF on your form: http://trompelecode.com/2010/12/animated-progress-indicator-in-csharp-windows-forms/
Sprite Animation
Let's say you need to accurately represent each image exactly (which isn't necessary if you're simply trying to look appealing), and that you don't want the overhead of a video system (which is okay if you're only playing a second or two worth of animations). What you want to do then is create a single composite "sprite" image. This reduces the memory overhead requirements of your application and reduces the amount of time decompressing files.
For example, here's a website that generates PNG sprites for you: http://wearekiss.com/spritepad
Once you generate an image with sprites, you can place it within a picturebox and animate the image by changing the relative position of the image within the picturebox. Here's a walkthrough of how to accomplish this: C# picturebox load image with an offset
Summary
Any way you choose to display an animated image, you will have some tradeoffs. I like to pick the simplest possible solution for myself - and in my case I like to use an animated GIF image. Good luck animating!
The .avi is alternative otherwise, however, if you have bunch of images than probably utilizing threads/timers apparently seems to be the way forward.
The easiest way would be to use an animated gif in that pictureBox and don't mess with timers.
You may also be able to put your animation together using WPF or Silverlight ... if you need the animation to be interactive or programmatically controllable that would probably be the way to go.
If on the other hand the animated content is static then AVI (or MPEG etc.) is probably your best bet.
You don't say exactly what you're trying to accomplish so I can't be sure.
I have a requirement to play a video file in C# (with audio) then to be able to fade out the video to a black screen then fade in another video.
I've looked at DirectShow & DirectShowNet however I'm none the wiser. I've got a simple app to play a video with a time counter etc, however I'm flummoxed with filters & graphs.
What direction do I need to go in?
Create a WPF Apllication and use the MediaElement Control to play the videos. Use the events of the MediaElement (for example MediaEnded) to detect when to start fadeout / switch streaming source / fadein. The easiest way for the fadeout is to change opacity of the Mediaelement.
The MediaElement should be able to play all videos which have a directshow filter installed on your system.
Are you using WPF?
With WPF you could do this in a variety of ways. eg you could simply animate the video control's (MediaElement) opacity.
NOTE: you can use WPF controls inside of a Winforms app. See this video for how to do this.
One solution, although I would consider it a hack, would be to draw a black overlay ontop of the viewable area of the video. You can adjust the transparency of the overlay based on the frame/time of the video. Essentially, you would fire off a timed event that would slowly remove or add transparency to the overlay based on where in the video you want to starting fading.