c# DirectShow example shows black screen, but sound is OK - c#

DirectShowLib.DVB-T example "DTVViewer" plays audio, but doesn't play video, I think it's because of H.264 video compressor, which is used in our Digital television and "DTVViewer" is trying to decompress MPEG2.
I want to ask how to form Graph and what filters to use to make "DTVViewer" support H.264?
CurrentGraph.
"MPEG2 DEMULTIPLEXER" pins:
(1)->BDA MPEG2 TRANSPORT INFORMATION FILTER
(2)->DScaler Mpeg2 Video Decoder->Video Renderer
(3)->AUDIO PART...
(5)->MPEG-2 SECTIONS AND TABLES
(ViPin) = AMMediaType(formatType?majorType?subType?)->Filter?->Video Renderer
Thinking, that now i only need help to configure new VideoPin correctly and add some H.264 decoder to it. Can anyone suggest something?
Thank you.

Try using Geraint Davies' free mpeg4 demux available at http://www.gdcl.co.uk/mpeg4/ instead of mpeg2 demultiplexer

If you are using Windows 7, you could look at using the Microsoft decoders. Take a look at the graph at this question: best way to build graph for MPEG2 transport stream.
As for what to specify for the video type, I use major type = video, subtype = H264, format type = video info.

Related

How to record two audio inputs and one video input?

I am trying to record two audio input (webcam + microphone) and one video input (webcam) via MediaCapture from C#. Just 1 audio and 1 video input works like a charm but the class itself does not allow to specify two audio input device ids.
An example:
var captureDeviceSettings = new MediaCaptureInitializationSettings
{
VideoDeviceId = videoDeviceId, #Webcam video input
AudioDeviceId = audioDeviceId, #Webcam audio input
StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo,
}
I thought about using audio graph and using a submix node but, I need to specify a device ID for the media capture, the submix node does not give that. Further on, using the output device of audio graph seems not like the solution, I do not want to play microphone to default output device. Tried that but sounds horrible. I thought about creating a virtual audio device but I don't know how.
Any suggestions on that?
MediaCapture won't be able to do this, WASAPI maybe possibile, but it is not trivial to do.
Best option may be to utilize https://learn.microsoft.com/en-us/windows/win32/coreaudio/loopback-recording.
You will still have to mux in video stream though if you get loopback recording to work.

Choose another source from usb device using directShow

I'm trying to get image from a usb device using Aforge (directShow). The device (USB3HDCAP) has 3 diferent inputs (HDMI, DVI and S-Video). Using the code above, i can access and get the default input image (only from HDMI). However, when I change the physical input on the device (from HDMI to DIV, example) the image is black. What can i do to get video from other input (DVI or S-Video).
LocalWebCamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
LocalWebCam = new VideoCaptureDevice(LocalWebCamsCollection[0].MonikerString);
LocalWebCam.NewFrame += new NewFrameEventHandler(Cam_NewFrame);
LocalWebCam.Start();
Your code snippet is what just captures video. To switch inputs on video capture hardware you need to use crossbar to re-configure the device.
In plain DirectShow it is like his:
Crossbar filter change current input to Composite
DirectShow USB webcam changing video source
With AForge.NET you should be looking up for a similar method, e.g. see:
Start Capturing From S-Video
... VideoCaptureDivece.AvailableCrossbarVideoInputs gives array of available video inputs. VideoCaptureDivece.CrossbarVideoInput accepts what? - yes video input. So combine those two together:
VideoKaynagi.CrossbarVideoInput = CrossbarVideoInput.AvailableCrossbarVideoInputs[0];
Of course you need to change 0 with an index of the S-Video input.

How to preview/display video from bytes

How could I display/preview input video using Black Magic Design DecklinkAPI.dll? I could get video frame by frame but I do not know how could I display the frame in the Form/Window. I could implement IDeckLinkInputCallback:
void IDeckLinkInputCallback.VideoInputFrameArrived(IDeckLinkVideoInputFrame video,
IDeckLinkAudioInputPacket audio)
{
IntPtr pData;
video.GetBytes(out pData);
// What should I do to get the preview?
System.Runtime.InteropServices.Marshal.ReleaseComObject(video);
}
Another way I see is to implement IDeckLinkScreenPreviewCallback:
void IDeckLinkScreenPreviewCallback.DrawFrame(IDeckLinkVideoFrame theFrame)
{
// Constructor: m_ph = new CDeckLinkDX9ScreenPreviewHelper();
m_ph.SetFrame(theFrame);
// Should I use this method instead to get the preview?
System.Runtime.InteropServices.Marshal.ReleaseComObject(theFrame);
}
There more complete code samples but they are still missing the important bit of code:
blackmagic SDK in c#.
BMD Decklink SDK documentation could be found here.
Thanks.
If you are using DeckLink SDK to capture video, then it is your responsibility to convert frames into format, which can be consumed by presentation API (GDI, GDI+, DirectShow, Media Foundation etc) - certain effort is expected here since you typically capture in non-RGB pixel format, and possibly at non-standard stride.
Alternatively, you can use DeckLink DirectShow video capture source which captures video and makes it available as a feed compatible with DirectShow API. You can use standard components to preview and process video. You can build and control DirectShow graphs in C# through DirectShow.NET library.

How to capture screen to be video using C# .Net?

I know there are lots of question like this.
But I don't want to use the Windows media encoder 9 because it's a problem to get one, and then it is no longer supported.
I know that, one possibility is to capture lots of screenshots and create a video with ffmpeg but I don't want use third party executables.
Is there are a .net only solution?
the answer is the Microsoft Expression Encoder. It is according to my opinion the easiest way to record something on vista and windows 7
private void CaptureMoni()
{
try
{
Rectangle _screenRectangle = Screen.PrimaryScreen.Bounds;
_screenCaptureJob = new ScreenCaptureJob();
_screenCaptureJob.CaptureRectangle = _screenRectangle;
_screenCaptureJob.ShowFlashingBoundary = true;
_screenCaptureJob.ScreenCaptureVideoProfile.FrameRate = 20;
_screenCaptureJob.CaptureMouseCursor = true;
_screenCaptureJob.OutputScreenCaptureFileName = string.Format(#"C:\test.wmv");
if (File.Exists(_screenCaptureJob.OutputScreenCaptureFileName))
{
File.Delete(_screenCaptureJob.OutputScreenCaptureFileName);
}
_screenCaptureJob.Start();
}
catch(Exception e) { }
}
Edit Based on Comment Feedback:
A developer by the name baSSiLL has graciously shared a repository that has a screen recording c# library as well as a sample project in c# that shows how it can be used to capture the screen and mic.
Starting a screen capture using the sample code is as straight forward as:
recorder = new Recorder(_filePath,
KnownFourCCs.Codecs.X264, quality,
0, SupportedWaveFormat.WAVE_FORMAT_44S16, true, 160);
_filePath is the path of the file I'd like to save the video to.
You can pass in a variety of codecs including AVI, MotionJPEG, X264, etc. In the case of x264 I had to install the codec on my machine first but AVI works out of the box.
Quality only comes into play when using AVI or MotionJPEG. The x264 codec manages its own quality settings.
The 0 above is the audio device I'd like to use. The Default is zero.
It currently supports 2 wave formats. 44100 at 16bit either stereo or mono.
The true parameter indicates that I want the audio encoded into mp3 format. I believe this is required when choosing x264 as the uncompressed audio combined in a .mp4 file would not play back for me.
The 160 is the bitrate at which to encode the audio.
~~~~~
To stop the recording you just
recorder.Dispose();
recorder = null;
Everything is open source so you can edit the recorder class and change dimensions, frames per second, etc.
~~~~
To get up and running with this library you will need to either download or pull from the github / codeplex libraries below. You can also use NuGet:
Install-Package SharpAvi
Original Post:
Sharp AVI:
https://sharpavi.codeplex.com/
or
https://github.com/baSSiLL/SharpAvi
There is a sample project within that library that has a great screen recorder in it along with a menu for settings/etc.
I found Screna first from another answer on this StackoverFlow question but I ran into a couple issues involving getting Mp3 Lame encoder to work correctly. Screna is a wrapper for SharpAVI. I found by removing Screna and going off of SharpAvi's sample I had better luck.

Create Video out of image files?

I'm trying to make a video out of a folder full of jpeg files. I tried Google, and everybody is stuck with this. I have downloaded the WM SDK and the Encoder, but since the moment I don't know their object model I cant do much.
Does somebody here have some code WORKING about how to create a WMV or an AVI or a MPEG video file out of a folder full of jpegs? (In C#)
I can see on the answers that apparently there is no way to do it from C#, just using a third party. I will check your suggestions.
Take a look at Corinna John's AVIFile wrapper. I used it in the AVI output plugin for Cropper.
VirtualDub is capable of making a video out of several image files. Here's a quite overview of how to do it.
FFMPEG, as CptSkippy mentioned, also has this feature.
See the AVBlocks Slideshow sample. It creates a video (like MP4) from images. The input is a series of JPEG images. The output is configured with an AVBlocks preset.
Try via NuGet "accord.extensions.imaging.io", then I wrote the following little function:
private void makeAvi(string imageInputfolderName, string outVideoFileName, float fps = 12.0f, string imgSearchPattern = "*.png")
{ // reads all images in folder
VideoWriter w = new VideoWriter(outVideoFileName,
new Accord.Extensions.Size(480, 640), fps, true);
Accord.Extensions.Imaging.ImageDirectoryReader ir =
new ImageDirectoryReader(imageInputfolderName, imgSearchPattern);
while (ir.Position < ir.Length)
{
IImage i = ir.Read();
w.Write(i);
}
w.Close();
}
It reads all images from a folder and makes a video out of them.
If you want to make it nicer you could probably read the image dimensions instead of hard coding, but you got the point.
Have you considered using FFMPEG? I've used it to create thumbnails from video in several projects.
I finally settled on Splicer. Free, simple to use, and it works. More info at Working way to make video from images in C#

Categories

Resources