Pregunta

Soy completamente nuevo en la entrada de video, y comencé a trabajar con Aforge hace unos días. Trabajar con video en vivo es cómodo, pero ahora necesito hacer algo con archivos para un proyecto.

Usando el códec VCM de Windows Media Video 9, el guardar no ha sido un problema. El archivo de salida funciona normalmente con cada jugador que tengo, pero mi programa siempre lo reproduce al doble de la velocidad de cuadro. Esto es especialmente extraño ya que nunca hay ninguna indicación de que la velocidad de fotogramas se cambie: tanto el valor predeterminado con el que se guardó el video y el nuevo reproductor indica que la velocidad de cuadro es de 25 fps.

Las únicas sugerencias que he encontrado son cambiar la velocidad de fotogramas antes de capturar el video, pero esto parece no hacer nada.

Mirando a su alrededor en la documentación de AviFilevideOsource, encontré las propiedades FrameIntervalFromSource y FrameInterval que, juntas, deberían darme los resultados que estoy buscando, pero tampoco puedo hacer que funcionen. Todo lo demás ha sido un callejón sin salida, y no tengo ideas. Aquí está el código que estoy usando para leer el archivo:

    public partial class Form1 : Form
{
    AVIReader input = new AVIReader();
    AVIFileVideoSource source = new AVIFileVideoSource("test.avi");

    public Form1()
    {
        InitializeComponent();
    }

    public void cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        input.Open("test.avi");
        for (int i = 0; i < input.Length; i++)
        {
            pictureBox1.Image = input.GetNextFrame();
        }
        source.Stop();
        input.Close();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        source.NewFrame += new NewFrameEventHandler(cam_NewFrame);
        source.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        source.Stop();
        input.Close();

    }
}

Cualquier otra sugerencia sería muy apreciada. Gracias por tu tiempo.

¿Fue útil?

Solución

Encontré una solución de trabajo al problema al buscar otras áreas de la biblioteca. En esta solución, había otras dos clases que estaba pasando por alto: DirectShow, que ya estaba referenciado y control. Específicamente, necesitaba usar instancias de FileVideoSource y VideoSourcePlayer para obtener el video en algo con lo que pudiera trabajar.

Esta versión es diferente de lo anterior, ya que tanto las funciones de lectura como la escritura se han combinado en un solo programa. Además, tenía una apuro para hacer esto, por lo que todavía es bastante frágil. Sin embargo, aquí está mi solución:

    public partial class Form1 : Form
{
    public Bitmap newBitmap;
    public VideoCaptureDevice cam = null;
    public FilterInfoCollection usbCams;

    AVIReader reader = new AVIReader();
    AVIWriter writer = new AVIWriter("wmv3");
    AVIFileVideoSource source = new AVIFileVideoSource("test.avi");

    FileVideoSource normSource = new FileVideoSource("test.avi");
    VideoSourcePlayer player = new VideoSourcePlayer();

    public Form1()
    {
        InitializeComponent();
    }

    public void cam_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        Bitmap image = (Bitmap)eventArgs.Frame.Clone();
        writer.AddFrame(image);

        pictureBox1.Image = image;
    }

    public void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        newBitmap = (Bitmap)eventArgs.Frame.Clone();
        pictureBox1.Image = newBitmap;
    }

    private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image)
    {
        videoSourcePlayer1.VideoSource = normSource;
        videoSourcePlayer1.GetCurrentVideoFrame();

        videoSourcePlayer1.DrawToBitmap(newBitmap,
            new Rectangle(0, 0, image.Width, image.Height));
    }

    private void button1_Click(object sender, EventArgs e)
    {
        source.NewFrame += new NewFrameEventHandler(video_NewFrame);
        source.Start();
        videoSourcePlayer1.NewFrame += new AForge.Controls.VideoSourcePlayer.NewFrameHandler(videoSourcePlayer_NewFrame);
        videoSourcePlayer1.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        if (source.IsRunning == true)
        {
            source.Stop();
            videoSourcePlayer1.Stop();
        }

        if (cam != null)
        {
            cam.Stop();
            writer.Close();
        }
    }

    private void button3_Click(object sender, EventArgs e)
    {
        usbCams = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        cam = new VideoCaptureDevice(usbCams[0].MonikerString);
        cam.DesiredFrameSize = new Size(320, 240);

        writer.Open("test.avi", 320, 240);

        cam.NewFrame += new NewFrameEventHandler(cam_NewFrame);
        cam.DesiredFrameRate = 25;
        cam.Start();
    }
}

Gracias por leer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top