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();

ボタンをクリックすると、ファイルが再生され、最初にメッセージボックスに継続時間が表示されます。表示: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メソッドを呼び出して、期間がどの単位であるかを確認する必要があります。最も可能性の高いデフォルト値は、マイクロ秒の10分の1であるTIME_FORMAT_MEDIA_TIMEです。

その場合、期間を10 * 1000 * 1000で割って、秒を取得します。

単位を強制する場合は、GetDurationを呼び出す前にSetTimeFormatを呼び出すこともできます。

したがって、あなたの場合はGetTimeFormat()、単位を計算し、それを使用してオブジェクトの正しい単位に変換しTimeSpanます。

于 2012-11-29T21:09:04.720 に答える