We are developing an app to take video files in various formats, perform some simple editing to the files, and output them to a specific format.
I can handle everything except for the editing part through FFMPEG, as the editing requires a user to specify certain things. I need a user to specific any frame ranges that need to be trimmed (only from the beginning or end, never the middle), start/end frame numbers for fading in or out, and overlay text.
I've seen both Splicer and the Directshow.NET wrappers, but I'm not sure it's worth the time to bring all of the editing into our app, and not just use avisynth/ffmpeg/mencoder to perform the actual editing after the user sets all of the above things.
All I really need is a control or wrapper so I can create a control that will play/pause a video, move between frames, and let me grab that specific frame number of the video. I can generate AVS files from that to do the rest. It'd be nice if it would use DirectShow at some level so that any codecs installed on the machine will be available, as the videos could be in WMV, FLV, Divx, MP4, etc. to begin with and we need to support all of those.
Any ideas or suggestions will be considered, but we are going for the fastest (code writing, not execution) implementation.
What we ended up doing:
We used the Windows Media Player ActiveX control to let the user select points in the video to set for the fades and trimming. We then generate an Avisynth script from that and run it through mencoder to get the final video.
We settled on using the double property from the WMP control that specifies the currentPosition in the clip playing. This was precise enough for our needs to generate a frame number from the clip's frames per seconds and currentPosition to use in the AviSynth script.
Related
I need a very simple video player in my C# app. It only has to loop a video from file and nothing more. Since I'm developing a WPF application, I've tried to use System.Windows.Controls.MediaElement. It has all the functions I need, but works quite poor: I've played some full HD videos on it, and it's always lagging and spiking.
To make sure, it's not my app problem, I've created 2 test applications. The first in a WinForms borderless 1920x1080 window with only AxWMPLib.AxWindowsMediaPlayer control. And the second in a borderless WPF window of the same size with System.Windows.Controls.MediaElement.
Then I run 2 videos on both of players. Here are their specs:
1: 1920x1080, 12000kb/s, 25 FPS, wmv
2: 1920x1080, 5730kb/s, 25 FPS, mp4
On AxWindowsMediaPlayer everything looks fine. But MediaElement seems to drop some frames and ignore vertical sync (it's possible to see parts of one frame on another during fast scene changes). So, it's completely unsuitable and shouldn't be like that, but I've found nothing about the problem in Microsoft official docs (they only suggest to use MediaElement instead of AxWindowsMediaPlayer in WPF apps). Is it possible to make it work more smoothly or using an additional WinForms Form with AxWindowsMediaPlayer is the only solution?
It was written over five years ago (look up James Dailey messages in the thread), there were possibly some improvements but overall I suppose the statements are still in good standing. I will pick up some relevant quotes:
As you know the WPF environment is constructed from the ground up to offer developers a very rich “graphics first” environment. The MediaElement in particular was designed to allow you to mix video with various other UI components seamlessly. This solution will give you the flicker free, “draw over video” solution that you are looking for. The best part is you can do all of this in C#. The bad part of this solution is that the MediaElement is not designed for displaying time sensitive media content. In other words, the MediaElement is notorious for dropping and delaying the display of video frames. There are ways to minimize this such as using SD rather than HD content, use a video accelerated codec, etc.
also:
Unfortunately you can’t really tell the WPF MediaElement to never drop frames. The term we use for this class of issues is “disparate clocks”. In this case WPF is updating the screen at a certain rate (clock 1). The MediaElement (based on WMP) is cranking out video frames at a slightly different rate (clock 2). Given the underlying technologies there is currently no way to synchronize the two clocks and force them to “tick” at the same rate. Since the display will only be updated according to the WPF clock, multiple frames of video may be sent from the MediaElement to WPF between clock ticks. Because of this the MediaElement may appear to drop frames. This is a very common problem in multimedia development and there is no simple solution.
Windows Media Player uses Media Foundation and DirectShow APIs which power media playback with high quality video experience.
The basic Idea is this.
I am writing a text in top of a paused video and I want to take a snapshot of it
but the RenderTargetBitmap api doesnt work with video content and only renders the text with black backround. and the Screencapture api only works with the mobile device family and only renders the video and not the text.
Are there any other way to do this using pure c#?
It is very simple. Draw a text on top of a paused media element and take a screenshot of it and save it to a file, why is it so hard to do this?
It is possible to participate in any manner of data manipulation associated with a MediaElement provided you have a Component that is wired into the Media Extensions video pipeline.
Examples are given in the following links:
https://github.com/mmaitre314/MediaReader
https://code.msdn.microsoft.com/windowsapps/media-extensions-sample-7b466096
The first link provides a fully functional solution.
Hi I answered a similar question here for a similar problem that I encountere writing an UWP app. In my case I needed a snapshot of the UI where could possibily be more than one MediaElement dinamically loaded with a bunch of other elements (Images, texts, ...).
The solution I came up with is not so linear but still working. When I need the snapshot:
I extract the video frame and saved on disk for the time I needed it (you can find how in the other answer I wrote);
I create a new dynamic Image with the saved framed e put on top of the MediaElement in the UI;
Here you can create another "layer" with your text
At this point you can use RenderTargetBitmap to take your snapshot and dispose the Image on the UI. Don't forget to delete the file from disk like I do the first time....
I want to create a windows Forms program where I play an AVI file.
I want to be able to play it in full speed, to pause, to get the total number of frames, and to show a given frame (seek).
The AVI file has metadata for the file AND metadata per frame.
I want to do this in a windows Forms application in C#, or if it is really necessary using C++.
Internet search shows me a lot of possibilities to use: DirectX, DirectShow, Windows Media Player, Microsoft DirectX9, GNU code, and several other methods.
Alas I haven't seen one that supports all that I want, especially the metadata per frame is not used often.
It seems that several of these methods are obsolete, for instance to be able to use Microsoft DirectX I need to add "useLegacyV2RuntimeActivationPolicy".
So anyone who knows what method is the latest and greatest method to use in windows programming? Which method allows me to show metadate-per-frame?
I know it is possible to update a live tile in Windows 8 with image and text. But, I wanted to update the tile with a video.
Is it possible? If a video cannot be sent directly, can we break the video into many images and then update?
You cannot add video to the live tiles neither the gif images (you can add gif's but they won't work as intended). Adding video is not allowed since it'll consume lot's of system recourses in the background task. The purpose of live tile's are to show information not content itself so that user can just glance on it and take action if needed.
I want to create a simple video renderer to play around, and do stuff like creating what would be a mobile OS just for fun. My father told me that in the very first computers, you would edit a specific memory address and the screen would update. I would like to simulate this inside a window in Windows. Is there any way I can do this with C#?
This used to be done because you could get direct access to the video buffer. This is typically not available with today's systems, as the video memory is managed by the video driver and OS. Further, there really isn't a 1:1 mapping of video memory buffer and what is displayed anymore. With so much memory available, it became possible to have multiple buffers and switch between them. The currently displayed buffer is called the "front buffer" and other, non-displayed buffers are called "back buffers" (for more, see https://en.wikipedia.org/wiki/Multiple_buffering). We typically write to back buffers and then have the video system update the front buffer for us. This provides smooth updates, as the video driver synchronizes the update with the scan rate of the monitor.
To write to back buffers using C#, my favorite technique is to use the WPF WritableBitmap. I've also used the System.Drawing.Bitmap to update the screen by writing pixels to it via LockBits.
It's a full featured topic that's outside the scope (it won't fit, not that i won't ramble about it for hours :-) of this answer..but this should get you started with drawing in C#
http://www.geekpedia.com/tutorial50_Drawing-with-Csharp.html
Things have come a bit from the old days of direct memory manipulation..although everything is still tied to pixels.
Edit: Oh, and if you run into flickering problems and get stuck, drop me a line and i'll send you a DoubleBuffered panel to paint with.