gpt4 book ai didi

c# - 为什么当我尝试使用 directshow 将视频捕捉到 mp4 文件时,文件是空的?

转载 作者:太空宇宙 更新时间:2023-11-03 23:33:06 26 4
gpt4 key购买 nike

当我退出程序时,mp4 文件会自动删除。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DirectShowLib;
using DirectShowLib.BDA;
using DirectShowLib.DES;
using DirectShowLib.DMO;
using DirectShowLib.Dvd;
using DirectShowLib.MultimediaStreaming;
using DirectShowLib.SBE;
using System.Runtime.InteropServices;
using System.Management;
using System.IO;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Video.FFMPEG;
using AForge.Video.VFW;
using System.Drawing.Imaging;


namespace Youtube_Manager
{

public partial class Elgato_Video_Capture : Form
{
IFileSinkFilter sink;

IFilterGraph2 graph;
ICaptureGraphBuilder2 captureGraph;
Size videoSize;
string error = "";
List<Object> devices = new List<Object>();
IMediaControl mediaControl;

public Elgato_Video_Capture()
{
InitializeComponent();

if (comboBox1.Items.Count == 0)
{
for (int xx = 1; xx <= 8; xx++)
{
comboBox1.Items.Add(xx);
}
}

InitDevice();

}

IPin outPin;
IPin inPin;
private void InitDevice()
{
try
{
//Set the video size to use for capture and recording
videoSize = new Size(827, 505);//1280, 720);

//Initialize filter graph and capture graph
graph = (IFilterGraph2)new FilterGraph();
captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
captureGraph.SetFiltergraph(graph);
//Create filter for Elgato
Guid elgatoGuid = new Guid("39F50F4C-99E1-464A-B6F9-D605B4FB5918");
Type comType = Type.GetTypeFromCLSID(elgatoGuid);
IBaseFilter elgatoFilter = (IBaseFilter)Activator.CreateInstance(comType);
graph.AddFilter(elgatoFilter, "Elgato Video Capture Filter");

//Create smart tee filter, add to graph, connect Elgato's video out to smart tee in
IBaseFilter smartTeeFilter = (IBaseFilter)new SmartTee();

graph.AddFilter(smartTeeFilter, "Smart Tee");
outPin = GetPin(elgatoFilter, "Video");
inPin = GetPin(smartTeeFilter, "Input");

graph.Connect(outPin, inPin);

//Create video renderer filter, add it to graph, connect smartTee Preview pin to video renderer's input pin
IBaseFilter videoRendererFilter = (IBaseFilter)new VideoRenderer();

graph.AddFilter(videoRendererFilter, "Video Renderer");
outPin = GetPin(smartTeeFilter, "Capture");

inPin = GetPin(videoRendererFilter, "Input");
graph.Connect(outPin, inPin);

captureGraph.SetOutputFileName(MediaSubType.Avi, @"e:\screenshots\test1.mp4", out smartTeeFilter, out sink);
sink.SetFileName(@"e:\screenshots\test1.mp4", null);

//Render stream from video renderer
captureGraph.RenderStream(PinCategory.Capture, MediaType.Video, videoRendererFilter, null, null);
//Set the video preview to be the videoFeed panel
IVideoWindow vw = (IVideoWindow)graph;
vw.put_Owner(pictureBox1.Handle);
vw.put_MessageDrain(this.Handle);
vw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
vw.SetWindowPosition(0, 0, 827, 505);

//Start the preview
mediaControl = graph as IMediaControl;
mediaControl.Run();

}
catch (Exception err)
{
error = err.ToString();
}
}

IPin GetPin(IBaseFilter filter, string pinname)
{
IEnumPins epins;
int hr = filter.EnumPins(out epins);
checkHR(hr, "Can't enumerate pins");
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
bool found = (pinfo.name == pinname);
DsUtils.FreePinInfo(pinfo);
if (found)
return pins[0];
}
checkHR(-1, "Pin not found");
return null;
}

public void checkHR(int hr, string msg)
{
if (hr < 0)
{
MessageBox.Show(msg);
DsError.ThrowExceptionForHR(hr);
}
}
}

我现在将这部分添加到我的代码中:

captureGraph.SetOutputFileName(MediaSubType.Avi, @"e:\screenshots\test1.mp4", out smartTeeFilter, out sink);
sink.SetFileName(@"e:\screenshots\test1.mp4", null);

我看到了预览,但 mp4 文件是空的,它根本没有将视频保存到文件中。我想做的是使用 directshow 将视频流保存到 mp4 文件。现在我只能在 pictureBox 中看到视频的预览。

最佳答案

  1. 您捕获的不是 MP4 文件,而是仅带有 MP4 扩展名的 AVI 文件! DirectShow 没有原生的 MP4-Mux。您需要像 GDCL MP4 Mux 一样单独安装一个.

  2. 我认为您的连接工作不正常。使用 DirectShowNet,您需要检查返回码,然后自己抛出异常,例如:

    int hr = graph.Connect(outPin, inPin);;
    DsError.ThrowExceptionForHR(hr);
  3. 您的 captureGraph.RenderStream 没有用,因为 VideoRender-Filter 没有输出引脚。请看meaning of this function .您可以仅使用 RenderStream 更好地构建此图,它甚至会为您插入 SmartTee-Filter。

关于c# - 为什么当我尝试使用 directshow 将视频捕捉到 mp4 文件时,文件是空的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31468211/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com