2012-11-29 94 views
1

例如在标签或文本框中。 这是代码即时通讯目前正试图利用DirectShowLib-2005.dll如何在播放视频文件时播放剩余时间?

private void button5_Click(object sender, EventArgs e) 
     { 
      f = new WmvAdapter(_videoFile); 
      TimeSpan ts = TimeSpan.FromTicks(f._duration); 
      MessageBox.Show(ts.ToString()); 
      int t = 1; 
      const int WS_CHILD = 0x40000000; 
      const int WS_CLIPCHILDREN = 0x2000000; 
      _videoFile = Options_DB.get_loadedVideo(); 
      FilgraphManager graphManager = new FilgraphManager(); 

      graphManager.RenderFile(_videoFile); 
      videoWindow = (IVideoWindow)graphManager; 
      videoWindow.Owner = (int)pictureBox1.Handle; 
      videoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN; 
      videoWindow.SetWindowPosition(
       pictureBox1.ClientRectangle.Left, 
       pictureBox1.ClientRectangle.Top, 
       pictureBox1.ClientRectangle.Width, 
       pictureBox1.ClientRectangle.Height); 
      mc = (IMediaControl)graphManager; 
      mc.Run(); 

当我点击按钮的文件播放,我看到第一个在MessageBox.Show期间至极告诉我:00:02:47.4800000

所以首先是持续时间是错误的,因为文件播放长度是:00:04:36当我在硬盘上查看文件时。

我的目标是显示一些progressBar或没有progressBar现在只是在标签上剩下的时间向后播放视频。如果持续时间是00:04:36,所以我想显示它回去00:04:35 ... 00:04:34等等。

变量_duration很长,我试图将其转换为TimeSpan。 但是,视频长度与当我在硬盘上查看文件时不一样。

这是载体作用至极我不只是用它从类WmvAdapter创建:

private void SetupGraph(string file) 
     { 
      ISampleGrabber sampGrabber = null; 
      IBaseFilter capFilter = null; 
      IBaseFilter nullrenderer = null; 

      _filterGraph = (IFilterGraph2)new FilterGraph(); 
      _mediaCtrl = (IMediaControl)_filterGraph; 
      _mediaEvent = (IMediaEvent)_filterGraph; 

      _mSeek = (IMediaSeeking)_filterGraph; 

      var mediaFilt = (IMediaFilter)_filterGraph; 

      try 
      { 
       // Add the video source 
       int hr = _filterGraph.AddSourceFilter(file, "Ds.NET FileFilter", out capFilter); 
       DsError.ThrowExceptionForHR(hr); 

       // Get the SampleGrabber interface 
       sampGrabber = new SampleGrabber() as ISampleGrabber; 
       var baseGrabFlt = sampGrabber as IBaseFilter; 

       ConfigureSampleGrabber(sampGrabber); 

       // Add the frame grabber to the graph 
       hr = _filterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); 
       DsError.ThrowExceptionForHR(hr); 

       // --------------------------------- 
       // Connect the file filter to the sample grabber 

       // Hopefully this will be the video pin, we could check by reading it's mediatype 
       IPin iPinOut = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0); 

       // Get the input pin from the sample grabber 
       IPin iPinIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); 

       hr = _filterGraph.Connect(iPinOut, iPinIn); 
       DsError.ThrowExceptionForHR(hr); 

       // Add the null renderer to the graph 
       nullrenderer = new NullRenderer() as IBaseFilter; 
       hr = _filterGraph.AddFilter(nullrenderer, "Null renderer"); 
       DsError.ThrowExceptionForHR(hr); 

       // --------------------------------- 
       // Connect the sample grabber to the null renderer 

       iPinOut = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0); 
       iPinIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0); 

       hr = _filterGraph.Connect(iPinOut, iPinIn); 
       DsError.ThrowExceptionForHR(hr); 

       // Turn off the clock. This causes the frames to be sent 
       // thru the graph as fast as possible 
       hr = mediaFilt.SetSyncSource(null); 
       DsError.ThrowExceptionForHR(hr); 

       // Read and cache the image sizes 
       SaveSizeInfo(sampGrabber); 

       //Edit: get the duration 
       hr = _mSeek.GetDuration(out _duration); 
       DsError.ThrowExceptionForHR(hr); 
      } 
      finally 
      { 
       if (capFilter != null) 
       { 
        Marshal.ReleaseComObject(capFilter); 
       } 
       if (sampGrabber != null) 
       { 
        Marshal.ReleaseComObject(sampGrabber); 
       } 
       if (nullrenderer != null) 
       { 
        Marshal.ReleaseComObject(nullrenderer); 
       } 
       GC.Collect(); 
      } 
     } 

它之前,我转换为时间跨度是可变_duration期限:1674800000 我尝试了很多例子和东西,但我无法远离TimeSpan转换。

我该怎么做?

谢谢。

回答

0

这个问题似乎涉及:Determine length of audio file using DirectShow

答案有规定:

GetDuration返回,将需要多长时间才能播放该文件一个64位的整数值。

您需要调用GetTimeFormat方法来找出持续时间所处的单位。最可能的默认值是TIME_FORMAT_MEDIA_TIME,它是微秒的十分之一秒。

在这种情况下,您会将持续时间除以10 * 1000 * 1000以获得秒数。

如果你想强制单位,你也可以在调用GetDuration之前调用SetTimeFormat。

所以你的情况,我会使用GetTimeFormat()弄清楚的单位和使用将其转换为正确的单位为TimeSpan对象。

+0

GetTimeFormat需要得到(出guid pFormat)那是什么? –

+0

如果你还没有找到它,根据你提供的签名,你可以把它叫做'GetTimeFormat(out pFormat)',其中'pFormat'的类型是'guid'。 – Lunyx