2017-10-30 3 views
0

Mit diesem Code kann ich Videodateien von meiner Festplatte wiedergeben und das Video in pictureBox1 anzeigen. Aber ich frage mich, wie kann ich alle Frames des Videos in Bilddateien auf der Festplatte speichern? Während ich das Video spiele oder ohne zu spielen, muss ich die Frames irgendwie extrahieren und speichern.Wie kann ich mit directshowlib-2005 Frames aus Videos extrahieren?

Das ist mein gebrauchter Code so weit:

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 

     IGraphBuilder m_graphBuilder = null; 
     IMediaControl m_mediaCtrl = null; 
     IMediaEventEx m_mediaEvt = null; 
     IMediaPosition m_mediaPos = null; 
     IMediaSeeking m_mediaSeeking = null; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     void InitInterfaces() 
     { 
      try 
      { 
       m_graphBuilder = (IGraphBuilder)new FilterGraph(); 
       m_mediaCtrl = (IMediaControl)m_graphBuilder; 
       m_mediaEvt = (IMediaEventEx)m_graphBuilder; 
       m_mediaPos = (IMediaPosition)m_graphBuilder; 
       m_mediaSeeking = (IMediaSeeking)m_graphBuilder; 
      } 
      catch (Exception) 
      { 
       MessageBox.Show("Couldn't start directshow graph"); 
      } 
     } 


     void CloseInterfaces() 
     { 
      if (m_mediaCtrl != null) 
      { 
       m_mediaCtrl.StopWhenReady(); 
      } 
      m_mediaCtrl = null; 
      m_mediaEvt = null; 
      m_mediaPos = null; 

      m_mediaSeeking = null; 

      if (m_graphBuilder != null) 
       Marshal.ReleaseComObject(this.m_graphBuilder); 
      m_graphBuilder = null; 
     } 


     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 

     private void SetuupVideoRenderer() 
     { 
      IBaseFilter vmrFilter = null; 

      vmrFilter = (IBaseFilter)new VideoMixingRenderer(); 
      m_graphBuilder.AddFilter(vmrFilter, "Video Renderer"); 

      IVMRFilterConfig FilterConfig = (IVMRFilterConfig)vmrFilter; 
      FilterConfig.SetRenderingMode(VMRMode.Windowless); 

      IVMRWindowlessControl windowlessCtrl = (IVMRWindowlessControl)vmrFilter; 
      windowlessCtrl.SetVideoClippingWindow(this.pictureBox1.Handle); 
      windowlessCtrl.SetVideoPosition(null, DsRect.FromRectangle(pictureBox1.ClientRectangle)); 
      windowlessCtrl.SetAspectRatioMode(VMRAspectRatioMode.LetterBox); 

     } 
     private void buttonLoad_Click(object sender, EventArgs e) 
     { 
      openFileDialog1.Filter = "All Files (*.*)|*.*|mp4 (*.mp4)|*.mp4|mov (*.mov)|*.mov||"; 
      if (openFileDialog1.ShowDialog() == DialogResult.OK) 
      { 
       CloseInterfaces(); 
       InitInterfaces(); 

       SetuupVideoRenderer(); 
       m_graphBuilder.RenderFile(openFileDialog1.FileName, null); 

       textBoxDur.Text = (getDuration() * 0.0000001).ToString(); 
       m_mediaCtrl.Run(); 

       timer1.Enabled = true; 

      } 
     } 

     private void GetPosition(out long CurrentPos,out long StopPos) 
     { 

      m_mediaSeeking.GetPositions(out CurrentPos, out StopPos); 

     } 
     private long getDuration() 
     { 
      long duration; 
      m_mediaSeeking.GetDuration(out duration); 

      return duration; 

     } 

     private void SetPos(double fPos) 
     { 
      DsLong startPosition = (DsLong)(10000000 * fPos); 

      m_mediaSeeking.SetPositions(startPosition, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning); 


     } 
     private void buttonPause_Click(object sender, EventArgs e) 
     { 
      m_mediaCtrl.Pause(); 
     } 

     private void buttonPlay_Click(object sender, EventArgs e) 
     { 
      m_mediaCtrl.Run(); 

     } 
     private void OnVideoCompleted() 
     { 
      MessageBox.Show("Video Playback Completed"); 
     } 
     private void timer1_Tick(object sender, EventArgs e) 
     { 
      long iCurPos, iStopPos; 

      GetPosition(out iCurPos, out iStopPos); 

      if (iCurPos >= iStopPos) 
      { 
       timer1.Enabled = false; 
       OnVideoCompleted(); 
       return; 
      } 
      textBoxCurPos.Text = (iCurPos * 0.0000001).ToString(); 


     } 

     private void buttonGo_Click(object sender, EventArgs e) 
     { 
      SetPos(Convert.ToDouble(textBoxNewPos.Text)); 
      timer1.Enabled = true; 
     } 
    } 
} 
+0

Was Sie auf ur eigenen bisher versucht haben? –

+0

@L.Guthardt nicht viel, seit ich bin neu bei directorshowlib. Bis jetzt habe ich nur versucht, alle Variablen globalen Variablen wie m_mediaSeeking und m_mediaPos zu überprüfen, aber Sie können nur Informationen mit ihm erhalten. Ich habe auch versucht, imageBox1.Image.Save .... in einem Timer oder beim Start zu spielen, aber es scheint nicht logisch, es zu spielen und dann speichern Sie die Bilder aus der PictureBox1. Wenn ich ein Video von einer Stunde habe, dauert es eine Menge Zeit, alle Bilder zu speichern. –

+0

@L.Guthardt Nicht sicher, wo ich anfangen soll. Sagen wir, es ist möglich, aber ich bin mir nicht sicher, wie ich anfangen soll. –

Antwort

1

Ich denke, das excatly ist, was Sie suchen: extract frames of a video

Werfen Sie einen Blick auch bei diesen SO question und die Links auf diesen bereitgestellt Website.

Der einfachste Weg, es zu tun, ist in der Tat ein FFMPEG verwenden, da seine alredy einige der am häufigsten verwendeten Codecs enthält (wenn es Ihnen nichts ausmacht zusätzliche 30 + Mb auf Ihre App nicht). Wie für Wrapper, ich habe AForge Wrapper in der Vergangenheit und mochte es wirklich, weil es so einfach ist, mit zu arbeiten. Hier ist ein Beispiel aus seiner docs:

// create instance of video reader 
VideoFileReader reader = new VideoFileReader(); 

// open video file 
reader.Open("test.avi"); 

// read 100 video frames out of it 
for (int i = 0; i < 100; i++) 
{ 
    Bitmap videoFrame = reader.ReadVideoFrame(); 

    videoFrame.Save(i + ".bmp") 

    // dispose the frame when it is no longer required 
    videoFrame.Dispose(); 
} 

reader.Close(); 
Verwandte Themen