为什么DirectShow会加载视频字幕文件?

时间:2017-06-30 01:31:21

标签: c# video directshow directshow.net subtitle

我使用此类(来自CodeProject的found,删除一些方法和属性以减少代码)通过DirectShow播放视频文件,它工作正常。但如果字幕文件存在于播放文件的同一文件夹中,则会自动显示字幕。

我想知道哪些部分代码与字幕文件有关。我该如何删除或自定义它?! (例如颜色,字体大小,字体名称)

它在SampleGrabber过滤器内吗?!

class MediaPlayer : IDisposable
{
    public enum FileType
    {
        Video,
        Audio,
        Invalid
    }

    public enum GraphState
    {
        Stopped,
        Paused,
        Running,
        Exiting
    }

    public IVideoFrameStep frameStep = null;
    public FileType fileType = FileType.Invalid;
    public IGraphBuilder graphBuilder = null;
    public IMediaControl mediaControl = null;
    public IVideoWindow videoWindow = null;
    public IBasicVideo basicVideo = null;
    public ISampleGrabber sampleGrabber = null;
    public IMediaSeeking mediaSeeking = null;
    public IMediaPosition mediaPosition = null;
    public IMediaDet mediaDet = null;
    public IBasicAudio basicAudio = null;
    public IMediaEventEx mediaEvent;
    public Control control;
    public MediaInfo mediaInfo = new MediaInfo();
    public List<Frames> segmentationImages;
    private string filename;
    private ManualResetEvent manualResetEvent = null;
    volatile private GraphState currentState = GraphState.Stopped;
    public event HotMediaEvent StopPlay;

    public void Dispose()
    {
        CloseInterfaces();
    }

    ~MediaPlayer()
    {
        CloseInterfaces();
    }

    public MediaPlayer(string fileName)
    {
        try
        {
            IntPtr eventHandler;
            this.filename = fileName;
            this.SetupInterfaces(fileName);
            DsError.ThrowExceptionForHR(mediaEvent.GetEventHandle(out eventHandler));
            manualResetEvent = new ManualResetEvent(false);
            manualResetEvent.SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle(eventHandler, true);
            Thread t = new Thread(new ThreadStart(this.EventWait));
            t.Name = "HotMediaEvent Thread";
            t.Start();
        }
        catch
        {
            Dispose();
            throw;
        }
    }


    public void SetupInterfaces(string fileName)
    {
        this.graphBuilder = (IGraphBuilder)new FilterGraph();
        this.sampleGrabber = (ISampleGrabber)new SampleGrabber();
        ConfigSampleGrabber(this.sampleGrabber);
        this.graphBuilder.AddFilter((IBaseFilter)sampleGrabber, "SampleGrabber");
        DsError.ThrowExceptionForHR(this.graphBuilder.RenderFile(fileName, null));
        this.mediaControl = (IMediaControl)this.graphBuilder;
        this.mediaEvent = (IMediaEventEx)this.graphBuilder;
        this.mediaSeeking = (IMediaSeeking)this.graphBuilder;
        this.mediaPosition = (IMediaPosition)this.graphBuilder;
        this.videoWindow = this.graphBuilder as IVideoWindow;
        this.basicVideo = this.graphBuilder as IBasicVideo;
        this.basicAudio = this.graphBuilder as IBasicAudio;

        this.frameStep = this.graphBuilder as IVideoFrameStep;

        this.mediaDet = (IMediaDet)new MediaDet();
        this.mediaDet.put_Filename(fileName);
        this.CheckFileType();
        if (this.fileType == FileType.Video)
            this.GetMediaInfo();
    }


    public void SetupVideoWindow(Control control)
    {
        int hr = 0;
        this.control = control;
        if (this.fileType == FileType.Video)
        {
            //this.sampleGrabber.SetCallback(((MainForm)this.control.Parent.Parent), 1);
            this.GetMediaInfo();
            hr = this.videoWindow.put_Owner(control.Handle);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_WindowStyle((WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings));
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_Visible(OABool.True);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_MessageDrain(control.Handle);
            this.SizeWindow();
            DsError.ThrowExceptionForHR(hr);
        }
    } 

    public void ClearVideoWindow()
    {
        int hr = 0;
        if (this.fileType == FileType.Video)
        {
            hr = this.videoWindow.put_Owner(IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_Visible(OABool.False);
            DsError.ThrowExceptionForHR(hr);
            hr = this.videoWindow.put_MessageDrain(IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);
        }
    }

    private void CheckFileType()
    {
        int hr;
        if ((this.videoWindow != null) || (this.basicVideo != null))
            this.fileType = FileType.Video;
        else if ((this.basicAudio != null))
            this.fileType = FileType.Audio;
        else
            this.fileType = FileType.Invalid;

        OABool lVisible;
        hr = this.videoWindow.get_Visible(out lVisible);
        if (hr < 0)
        {
            if (hr == unchecked((int)0x80004002)) //E_NOINTERFACE
                this.fileType = FileType.Audio;
            else
                DsError.ThrowExceptionForHR(hr);
        }
    }

    private void EventWait()
    {
        int hr;
        //WS UPDATED changed int to IntPtr
        IntPtr firstParameter, secondParameter;
        EventCode eventCode;
        do
        {
            manualResetEvent.WaitOne(-1, true);
            lock (this)
            {
                if (currentState != GraphState.Exiting)
                {
                    hr = mediaEvent.GetEvent(out eventCode, out firstParameter, out secondParameter, 0);
                    while (hr >= 0)
                    {
                        if (eventCode == EventCode.Complete)
                        {
                            Stop();
                            if (StopPlay != null)
                                StopPlay(this);
                        }
                        hr = mediaEvent.FreeEventParams(eventCode, firstParameter, secondParameter);
                        DsError.ThrowExceptionForHR(hr);
                        hr = mediaEvent.GetEvent(out eventCode, out firstParameter, out secondParameter, 0);
                    }
                    if (hr != unchecked((int)0x80004004))
                        DsError.ThrowExceptionForHR(hr);
                }
                else
                    break;
            }
        } while (true);
    }

    public void SizeWindow()
    {
        int hr;
        Rectangle rc = control.ClientRectangle;
        int windowWidth, windowHeight;
        windowWidth = rc.Width;
        windowHeight = rc.Height;
        int videoWidth = this.mediaInfo.MediaWidth;
        int videoHeight = this.mediaInfo.MediaHeight;
        int x, y, width, height;
        double videoRatio = (double)videoWidth / (double)videoHeight;
        double windowRatio = (double)windowWidth / (double)windowHeight;
        if (videoRatio > windowRatio)
        {
            double ratio = (double)windowWidth / (double)videoWidth;
            x = (int)((windowWidth - videoWidth * ratio) / 2);
            y = (int)((windowHeight - videoHeight * ratio) / 2);
            width = (int)(videoWidth * ratio);
            height = (int)(videoHeight * ratio);
            hr = videoWindow.SetWindowPosition(x, y, width, height);
        }
        else
        {
            double ratio = (double)windowHeight / (double)videoHeight;
            x = (int)((windowWidth - videoWidth * ratio) / 2);
            y = (int)((windowHeight - videoHeight * ratio) / 2);
            width = (int)(videoWidth * ratio);
            height = (int)(videoHeight * ratio);
            hr = videoWindow.SetWindowPosition(x, y, width, height);
        }
        DsError.ThrowExceptionForHR(hr);
    }

    void ConfigSampleGrabber(ISampleGrabber sampGrabber)
    {
        AMMediaType media;
        media = new AMMediaType();
        media.majorType = MediaType.Video;
        media.subType = MediaSubType.RGB24;
        media.formatType = FormatType.VideoInfo;
        this.sampleGrabber.SetMediaType(media);
        DsUtils.FreeAMMediaType(media);
        media = null;
        int hr = sampGrabber.SetBufferSamples(true);
        DsError.ThrowExceptionForHR(hr);
    }

    private void GetMediaInfo()
    {
        AMMediaType media = new AMMediaType();
        this.sampleGrabber.GetConnectedMediaType(media);
        if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
        {
            throw new Exception("Format type incorrect");
        }

        int videoWidth, videoHeight, videoStride;
        this.basicVideo.GetVideoSize(out videoWidth, out videoHeight);
        VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));
        videoStride = videoWidth * (videoInfoHeader.BmiHeader.BitCount / 8);
        this.mediaInfo.MediaWidth = videoWidth;
        this.mediaInfo.MediaHeight = videoHeight;
        this.mediaInfo.MediaStride = videoStride;
        this.mediaInfo.MediaBitCount = videoInfoHeader.BmiHeader.BitCount;
        this.mediaInfo.fps = this.getFramePerSecond();
        this.mediaInfo.duration = this.getDuration();

        this.mediaInfo.sFilePath = this.filename.ToString();

        DsUtils.FreeAMMediaType(media);
        media = null;
    }


    private void CloseInterfaces()
    {
        lock (this)
        {
            int hr;
            try
            {
                if (this.mediaControl != null)
                {
                    hr = this.mediaControl.StopWhenReady();
                    this.mediaControl = null;
                }
                if (currentState != GraphState.Exiting)
                {
                    currentState = GraphState.Exiting;
                    if (manualResetEvent != null)
                        manualResetEvent.Set();
                }
                if (this.videoWindow != null)
                {
                    hr = this.videoWindow.put_Visible(OABool.False);
                    hr = this.videoWindow.put_Owner(IntPtr.Zero);
                    this.videoWindow = null;
                }
                this.mediaSeeking = null;
                this.mediaPosition = null;
                this.basicVideo = null;
                this.basicAudio = null;
                this.mediaDet = null;
                if (this.graphBuilder != null)
                    Marshal.ReleaseComObject(this.graphBuilder);
                this.graphBuilder = null;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return;
            }
        }
        GC.Collect();
    }


    public void Start()
    {
        if (this.currentState == GraphState.Stopped || this.currentState == GraphState.Paused)
        {
            DsError.ThrowExceptionForHR(mediaControl.Run());
            this.currentState = GraphState.Running;
        }
    }

    public void Stop()
    {
        if (this.currentState == GraphState.Running || this.currentState == GraphState.Paused)
        {
            DsError.ThrowExceptionForHR(mediaControl.Stop());
            currentState = GraphState.Stopped;
        }
    }


    public void End()
    {
        double endPosition = 0;
        this.mediaDet.get_StreamLength(out endPosition);
        DsError.ThrowExceptionForHR(mediaPosition.put_CurrentPosition(endPosition));
    }

}

1 个答案:

答案 0 :(得分:0)

最有可能的是你安装了DirectVobSub过滤器(通常作为某些编解码器包的一部分),它以高优点(优先级)注册自身,这允许它在过滤器图形构建过程中中断并插入到自身中您的管道甚至没有成为您的代码的一部分。

过滤器会查找字幕文件并自动加载,然后更新视频供稿。

  

DirectVobSub(以前称为VSFilter)是Microsoft Windows(DirectShow过滤器)的软件附加组件,能够读取外部字幕文件并将其叠加在播放视频文件上。

您想要将其卸载,或禁用它的自动自动激活功能。

另见: