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。

我的目标是现在仅在标签上显示一些进度条或不显示进度条,以便向后播放视频。如果持续时间是 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();
            }
        }

在我将其转换为 TimeSpan 之前的持续时间在变量 _duration: 1674800000 我尝试了很多示例和东西,但我离 TimeSpan 转换不远了。

请问我该怎么做?

谢谢你。

4

1 回答 1

0

这个问题似乎相关:使用 DirectShow 确定音频文件的长度

那里的答案是:

GetDuration 返回一个 64 位整数值,表示播放文件需要多长时间。

您将需要调用 GetTimeFormat 方法来找出持续时间的单位。最可能的默认值是 TIME_FORMAT_MEDIA_TIME,即 10 微秒。

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

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

所以在你的情况下,我会用GetTimeFormat()它来计算单位并用它来将它转换为TimeSpan对象的正确单位。

于 2012-11-29T21:09:04.720 回答