I'm developing a Windows 8 Store App, I have this problem,
I want the user to add the videos from a file picker and i managed it,
the problem is I want to display the videos images in a GridView,
like snap shot of the video in a certain position, i tried the media element and it's not working
also an image and it doesn't make sense.
There might not be a pure C# solution to this problem. Perhaps SharpDX would let you do that, but I haven't tried and I don't know if it was done before. If you look at these two threads:
http://social.msdn.microsoft.com/Forums/fil-PH/wingameswithdirectx/thread/05731d4f-5b7f-4ed1-8e28-94604655139e
http://social.msdn.microsoft.com/Forums/en/wingameswithdirectx/thread/ffacd05c-6e9e-43bf-b691-99127240730c
-- you should see that there is a TransferVideoFrame method you can use to copy a frame from a video stream to a DirectX texture. The Media engine native C++ video playback sample shows how you can use it natively. If you search for TransferVideoFrame+SharpDX - you can find this sample that uses the SharpDX version of this method in C#. After you transfer that frame to a texture - you can either copy the contents of the texture to a WriteableBitmap using the Map and Unmap methods like here. You can also save it to a file either using BitmapEncoder a here or directly from the DirectX texture to a file using WIC or say SharpDX Toolkit as in here. You will probably want to build a cache of thumbnails to avoid having to process the videos every time you display the list, so saving to a file is something you should do anyway.
Your own solution that you quoted elsewhere that should work for at least some videos:
var thumb = await
storageFile.GetThumbnailAsync(
Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
1000,
Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale);
I suggest using GetThumbnailAsync(), which works just as well. You don't even need to get the video properties or anything like that. If the StorageFile is loaded, this should work for a normal video of any format.
Related
I've got some C# code in Unity that grabs a large image from my Android Device's filesystem, and now with it I want to use it to create a small thumbnail image.
I've found lots of different suggestions for how to do this such as the following:
MemoryStream outputStream = new MemoryStream();
System.Drawing.Image image = System.Drawing.Image.FromFile(originalImagePath);
System.Drawing.Image thumbnail = image.GetThumbnailImage(thumbnailWidth, thumbnailHeight,()=>false, IntPtr.Zero);
thumbnail.Save(outputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
return outputStream;
However, as with the above method, all of the methods I've found require you to use the System.Drawing namespace. And I can't for the life of me get the functions in this namespace to work on Android, because even after adding "System.Drawing.dll" into the Assets folder, I get an error saying that it can't locate "gdiplus.dll" on construction of "System.Drawing.Image". I tried downloading and adding said "gdiplus.dll" to Assets, but I just get the same error as if it can't find it!
I don't understand why its so hard to get the System.Drawing functions working in Unity, but that's somewhat besides the point, as all I really want to do is create a thumbnail of an image that lives on the user's Android Device. Any suggestions would be welcome!
EDIT: I forgot to mention that I'd like to avoid solutions that use Texture2D's because they can't be run off the main thread, and hence come with performance consequences =(
Thanks in advance! =)
Don't use Texture2D.Resize, because the resulting texture will become grey:
After resizing, texture pixels will be undefined.
See this post for other solutions.
Old answer
I recommend use an opensource C# image processing library, such as ImageSharp or search it on GitHub.
The last solution is to write one yourself, if the performance or size of a 3rd-party library is still not good enough.
Here are two ideas I can come up with:
split the possibly lengthy reading and resizing procedure into several Coroutines.
use multi-thread
You may also try calling java functions from Unity3D. But I'm not familiar with that.
I am attempting to save a video file (e.g., .AVI file) from the Kinect's RGB stream.
I am using the latest Kinect SDK (1.5)
I tried using e2e's DirectShow filters and it didn't work, there must be a more straight forward approach.
I tried the colorBasics method of writing each frames as .png files. But, then the speed reduced to 6fps from 30fps. I guess, multi-threading may help to increase the performance. I dont know how to multi thread it, is there any online source of it. I searched a lot, but no luck yet.
Thanks.
The Kinect does not directly support recording straight off the video streams. You can accomplish it by accessing each frame, as it comes in, and creating an AVI (or other video format) in code.
The Kinect Toolbox has a video recorder, you can look at the source as a starting point.
You can easily extract WriteableBitmap objects from the Kinect RGB camera. From that you can find a lot of information on creating still images to produce an AVI, or produce an AVI directly.
Google Search: Create AVI from still images
Google Search: Create AVI from WPF WriteableBitmap
Have a look at the "Color Basics" example from the Kinect for Windows Developer Toolkit to see how to access the camera and extract data to a WritableBitmap object.
I am looking for an effective way to grab image data off video files. I am currently testing FilgraphManagerClass.GetCurrentImage() from the Interop.QuartzTypeLib library. This does what I need but is painfully slow. I need to process all frames of each video. What better options do I have?
Requirements
Must be frame accurate. <-- Very important!
Gives me access to the decoded pixel buffer (array of int or byte[]), ideally RGB24 or RGB32.
The buffer can be grabbed in realtime or faster. I do not need to display the video, I only need to analyze the pixels.
Handle mp4 files (h264/aac). I can rewrap or frame serve via AviSynth if needed but no retranscoding can be involved.
Any suggestions would be welcome.
Some code as requested:
FilgraphManagerClass graphClass = new FilgraphManagerClass();
graphClass.RenderFile(#"C:\tmp\tmp.avs");
int sz = (graphClass.Width * graphClass.Height + 10) * 4;
int[] buffer = new int[sz - 1];
I am then stepping through each frame. I have something like this in the loop:
graphClass.GetCurrentImage(ref sz, out buffer[0]);
//DoStuff(buffer);
graphClass.CurrentPosition += graphClass.AvgTimePerFrame;
IBasicVideo::GetCurrentImage method you are using is basically intended for snapshots, and works with legacy video rendering in legacy modes only. That is, (a) it is NOT time accurate, it can get you duplicate frames or, the opposite, lose frames; and (b) it assumes that you display video.
Instead you want to build a filter graph of the following kind: File Source -> ... -> Sample Grabber Filter -> Null Renderer. Sample Grabber, a standard component, can be provided with a callback so that it calls you with any frame data that comes through it.
Then you remove clock from the graph by calling SetReferenceClock(null) on the filter graph so that it run as fast as possible (as opposed to realtime). Then you Run the graph and all video frames are supplied to your callback.
To accomplish the task in C# you need to use DirectShow.NET library. It's Capture\DxSnap sample provides a brief example how to use Sample Grabber. They do it through BufferCB instead of SampleCB and it works well too. Other samples there are also using this approach.
You will find other code snippets very close to this task:
Seeking keyframes using DirectShowNet - use of Sample Grabber
BufferCB not being called by SampleGrabber - same task for audio part
How to access an audio stream using DirectShow.NET C#
Regarding MP4 files you should take into consideration the following:
Support for MPEG-4 is limited in Windows, and you might need third party components installed to make the files playable. If GraphEdit can read them, then you can too.
Windows Media Player might be using, and is likely to, a newer API and you should rather look at GraphEdit
Be sure to use Win32/x86 platform on your application to avoid running into scenario that your app is running in 64-bit domain, while support for MP4 only exists in 32-bit components/libraries installed
You could also look at creating an allocator-presenter using Windows Media Foundation. This will give you the decoded video frame as a GPU texture and you could also use CUDA or OpenCL to perform the processing required (if possible) which would help your processing speed immensely.
I have a hard drives dedicated to videos, and I wanted to write a program that would move all my video files into folders based on their video playback size.
I was thinking about having it organized like this.
/HD/1080p/(FileName)/(fileName).ext
/HD/720p/(FileName)/(fileName).ext
(I know that not all video files are 1080 or 720p because of crop, but within +-20 to 30px.)
/SD/(FileName)/(fileName).ext //anything less then 720p
I know you are able to right click on a video file and go to properties then details and see the frame width and frame height, but I'm not sure you can view this information in C#.
I don't know where to start and some information would be awesome. like:
Moving files with c#, renaming them, Viewing file details (frame sizes, file type, name, lenght, etc.) I plan on making a DB on this information but as of right now I just want to move the files into the correct folders.
I have been doing this manually and it's very tedious and time consuming.
Any help would be awesome, Thanks,
Throdne
The best for getting file info properties is to use MediaInfo.dll. There is also c# wrapper available to collect all data you need from video file.
You can obtain media ifo from mediainfo.sourceforge.net
This is multiplatform and can be used on Mono and Linux as well on Windows.
I've put also some information about MediaInfo on following thread: https://stackoverflow.com/questions/9561490...
Your best bet is using something like DirectShow which will handle multiple video formats there is a com+ object you can attach to but on source forge there is a wrapper around the
API
Info on sourceforge
once you have that figured out you can then go
here to figure out how to move files around
hi
I am developing a video capture application using C#.net. i captured
video through webcam and saved it as a JPEG images then i want to make a
wmv file with those images. how can i do that what are the basic steps needed for that can any body help
I am working on this myself. I have found two ways that may be possible - both require the purchase of an outside library.
The first one looks to be the easiest but costs the most, although it will allow you to use it for free you will just have to deal with a pop up telling you to purchase the library: http://bytescout.com/products/developer/imagetovideosdk/imagetovideosdk_convert_jpg_to_video.html
The other involves using Microsoft Encoder 4. I am still working on this one. You can get the free version here: http://www.microsoft.com/download/en/details.aspx?id=18974
C# doesn't natively support much in the way of sound or video so outside reference assemblies seem to be a necessity.
Right now that is the best help I can offer until I figure it out.