Is there a way of using ffmpeg in c# app? - c#

I'm using the ffmpeg.org and when I run ffmpeg -y -f vfwcap -r 25 -i 0 out.mp4 in command line I can grab the video from my webcam and write it to the out.mp4 file. However, I can't see that stream anywhere. I thought about writing some simple wrapper in c# that is built on ffmpeg functionality, so far I found post mentioned on Stack before, but there's nothing about displaying the data live (instead of saving it into the file). Does anyone have any experience with it? Can I for example 'draw' the received data from webcam on a picture box or on some other component?
Thanks!

One of the comments in your linked post says this:
How about writing a C++/CLI wrapper around ffmpeg's native interface
and then calling your wrapper interface from your application?
I think this is exactly what you want to do. (Note that FFmpeg has worked fine for years in recent versions of Visual Studio, so the response in the linked post to this comment doesn't apply.)
You would basically create a camera input (this lives in libavdevice), and then you would encode this to h264 in a mp4 container (see output_example.c). To get a live display, you would take the data generated from the vfwcap source, decode it (using the "rawvideo" decoder in libavcodec). This gives you a AVFrame, which has the data pointers to display the image in any native UI element in your application, typically using direct3d or opengl. Read the documentation to learn more about all of this.

You could use a MediaElement or MediaPlayer control.
MediaElement is a UIElement that is supported by the Layout and can be
consumed as the content of many controls. It is also usable in
Extensible Application Markup Language (XAML) as well as code.
MediaPlayer, on the other hand, is designed for Drawing objects and
lacks layout support. Media loaded using a MediaPlayer can only be
presented using a VideoDrawing or by directly interacting with a
DrawingContext. MediaPlayer cannot be used in XAML.
MediaElement
Sample XAML:
<MediaElement Source="path\to\out.mp4" Name="myMediaElement"
Width="450" Height="250" LoadedBehavior="Manual" UnloadedBehavior="Stop" Stretch="Fill"
MediaOpened="Element_MediaOpened" MediaEnded="Element_MediaEnded"/>
MediaPlayer
//
// Create a VideoDrawing.
//
MediaPlayer player = new MediaPlayer();
player.Open(new Uri(#"sampleMedia\xbox.wmv", UriKind.Relative));
VideoDrawing aVideoDrawing = new VideoDrawing();
aVideoDrawing.Rect = new Rect(0, 0, 100, 100);
aVideoDrawing.Player = player;
// Play the video once.
player.Play();
Multimedia Overview on MSDN

Related

Limit scan area in Zxing.Net

I built a UWP XAML control that acts as a barcode/qrcode scanner using the zxing.net library (http://zxingnet.codeplex.com/). The control works fine, it previews the camera on the device and then captures a frame and let zxing process it. All a user has to do is to place it in a page and tell it what type of barcode to scan.
I am just facing one problem: How can I limit the scan area to the center of the captured frame? Sometimes there are multiple barcodes in the image and the library returns a result from one of the barcodes but I am interested in the barcode that is in the middle of the frame.
Is this possible with zxing.net? If so, how can I limit the scan area?
I don't know what code are you using. But I can give a hint based on my UWP barcode scanner
Inside CapturePhotoFromCameraAsync() Task you can find code that take "screenshot" frame from camera:
VideoFrame videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)_width, (int)_height);
await mediaCapture.GetPreviewFrameAsync(videoFrame);
You can get there SoftwareBitmap and eben convert to WritableBitmap.
SoftwareBitmap sb = videoFrame.SoftwareBitmap;
WriteableBitmap bitmap = new WriteableBitmap(sb.PixelWidth, sb.PixelHeight);
But now there is another question how to crop WriteableBitmap (you can find solution on SO or MSDN - it's not short) and how to convert back to SoftwareBitmap.

Synchronous sound playback from video source in VideoSourcePlayer control

I'm using the Video Source Player control from AForge.Controls to play a few video clips within a winforms application.
The code is something like this.
string fileName = #"C:\path\to\file.example";
videoSourcePlayer.VideoSource = new AForge.Video.AsyncVideoSource(new FileVideoSource(fileName), true);
videoSourcePlayer.Start();
The video file includes both audio and video streams, however as far I'm aware the control only handles video and not audio.
How can I then play the audio stream in a synchronous fashion with the video source player control?
Thank you.
EDIT:
The Video Source Player control has a event named NewFrame, which allows to determine the precise video position which could be useful to keep the audio being played synchronized with the video.
Since you mentioned:
I'm only looking for other alternative in which is possible to
reproduce the audio contained the video file and somehow keep it
synchronized with the video player control...
Maybe you can have a better luck by using a ElementHost and using WPF media control.
If this solution is eligible for you follow this steps:
Create a new WPF UserControl and add to your WindowsForms app.
In this UserControl add a media element and configure the way you want.
Build the solution.
Now in the toolbox must appear YourSolutionName Controls and you controls must be there.
Just drag it to your WindowsForms app and it must create an ElementHost.
I've created the UserControl as follow:
<MediaElement Name="VideoMediaElement"
Source="Media/Wildlife.wmv"
LoadedBehavior="Manual"/>
Just remember in this example this file must be side-by-side with your app in a Media folder. If you miss this step it will give you the strange and not helpful error 0xC00D11B1.
The loaded behavior Manual will give you the chance to control de video more freely.
After that you can do whathever you want in this UserControl like create Play and Pause:
internal void Play()
{
this.VideoMediaElement.Play();
}
And to access them in WindowsForms do this:
private void WindowsFormsButton_Click(object sender, EventArgs e)
{
var videoControl = this.MyElementHost.Child as VideoUserControl;
videoControl.Pause();
}
Hope this helps. WPF MediaElement is much more easy to seach for than other libs.

Cropping an image stored locally

I'm kind of a greenhorn to Windows Phone development and I've been looking for a way in order to crop an image already built into the project (Maybe even from the camera some day), but every package I've found has either had a fuss with Visual Studio, or throws argument exceptions. So I've decided that I will make my own function to do so.
However, I have not the slightest idea where to start. I'm pretty sure WriteableBitmap has something to do with it, and something to do with the following code:
Application.GetResourceStream(new Uri("/PhoneApp3;component/Assets/Flowers/Daff.jpg"));
So how would one start out with getting the pixel data or creating a new image and apply pixel data. And finally how would one save the result and reference it through the UI's image elements.
Use WriteableBitmapEx to crop images on Windows Phone. The way you solution will have to work is to manipulate the WritableBitmap.Pixels property. You first load in an image, change the Pixels property and transform the raw pixels into a saved image format like JPG or PNG. That's a lot of work so lucky for you WriteableBitmapEx does that for you.
First, install WritebleBitmapEx from NuGet:
Install-Package WriteableBitmapEx
Then you can load any image, crop it and save back to the MediaLibrary. Here's for example how to load a file from the app's XAP, crop to top-left 25% of the image and save to the "Saved Pictures" WP7/8 album.
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var bmp = new WriteableBitmap(0, 0).FromContent("Assets/ApplicationIcon.png");
var croppedBmp = bmp.Crop(0, 0, bmp.PixelWidth/2, bmp.PixelHeight/2);
croppedBmp.SaveToMediaLibrary("myImage.jpg");
}
When we run this code we can see the new cropped image:
I recently needed to do this and didn't want to use an external lib. Microsoft provide a good example on MSDN on how to do it (and is also very good at not causing memory leaks!)
http://code.msdn.microsoft.com/wpapps/Photos-Sample-a38a2c8e
Cheers,
Will

How can I mix Image with a Video stream from USB capture device using DirectShowLib in C#

I'm able to show a video stream in a window. I'm using DirectShow VideoMixingRenderer9 in C#. I have created an Image with sometext in it. Now, how can I mix this image with the video stream so that both video stream and text is shown in the capture window. I tried with ISampleGrabber filter but it doesn't work with all video device and capture screan only shows the text with black background but no video stream. So I don't want to use ISampleGrabber filter.
IVMRMixerBitmap9 interface should help you, which is implemented by the VMR. This is the link to MSDN:
[http://msdn.microsoft.com/en-us/library/windows/desktop/dd390451(v=vs.85).aspx][1]
The bitmap needs to have alpha values so that it can be blended with the rendered video.

Setting the transparency of a WPF ImageSource (equivalent to GDI Matrix33 = 0.5f)?

Does WPF have an equivalent to this?
ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(new ColorMatrix { Matrix33 = 0.5f }, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
In other words, can I adjust the transparency of a WPF ImageSource (or any other drawing related class e.g. BitmapImage), or is GDI the best choice here?
I don't intend to draw the image onto a window, so I think that rules out using the Image class(?)
(My line of thought with trying to use WPF instead of GDI is primarily because I'm under the impression that with WPF I can have hardware acceleration, but from what I've seen so far, it seems that it's only applying to a very limited subset of image manipulation)
check out WriteableBitmapEx, which provides a set of extension methods for manipulating bitmaps in memory with WPF and Silverlight.
There is nothing in WPF per-se that will allow you to do want, but the WPF/Silverlight class WriteableBitmap provides a fast, low-level API to drawing/manipulating and is native to WPF.
WriteableBitmapEx then builds on this by providing extension methods to do GDI-like operations. There is a Convolute function which allows convolving an image with a matrix, so you could do the above. Note WB-Ex is a silverlight library but they also provide an unmaintained WPF version which although incomplete, can be extended to keep up to date with the Silverlight version.
Other than that I'd suggest rolling your own. If all you wish to do is modify the opacity to 0.5f then rather than convolve I'd suggest writing a specific function to do that based on the above examples
An image has an opacity field, which is a value between 1.0 (completely opaque) to 0.0 (invisible)
For example:
<Image
Height="107"
Margin="367,0,473,83"
Source="Images/4.png"
Stretch="Fill"
VerticalAlignment="Bottom" Opacity="0.5"/>
Following your comments I created a sample project which can modify the alpha channel quickly using WriteableBitmapEx as a basis and uploaded to my Company Blog. You'll have to forgive the formatting, its a new website and still has some glitches to be ironed out! The download link is on the page titled BitmapAlphaChannel
You're correct in saying WPF's hardware acceleration is only applied to a limited subset of features. For instance, all layout is done on the CPU, tessellation on the CPU, only the final rendering is done on the GPU. The result is WPF in my experience is slower than GDI+, certainly GDI. However it can be pushed in the right direction to do what you want, in the speed you want it to!

Categories