C# How Can I Play A Video From A Memory Stream Using DirectShow(quartz.dll)?

百般思念 提交于 2019-12-11 14:47:31

问题


I have a C# Visual Studio WinForms .NET app that plays video using the QuartzTypeLib (quartz.dll). With the code I've written, I can play any video file from the hard drive.

Here's the code at the top that executes when the app starts:

    public const int WS_CHILD = 0x40000000;
    public const int WS_CLIPCHILDREN = 0x2000000;
    public QuartzTypeLib.IMediaControl mc;
    public QuartzTypeLib.IVideoWindow videoWindow = null;
    IMediaPosition mp = null;

And here's the code that opens the video file:

    private void openMediaToolStripMenuItem_Click(object sender, EventArgs e)
    {
        // Open a media file.
        OpenFileDialog ofd = new OpenFileDialog();
        ofd.Filter = "Video Files|*.mpg;*.avi;*;*.wmv;*.mov";
        ofd.FilterIndex = 1;
        if (DialogResult.OK == ofd.ShowDialog())
        { 
            // Stop the playback for the current movie if a video is currently playing.
            if (mc != null)
                mc.Stop();
            if (pbVideoDisplay.Image != null)
                pbVideoDisplay.Image = null;
            // Load the movie file.
            FilgraphManager graphManager = new FilgraphManager();
            graphManager.RenderFile(ofd.FileName);
            mp = graphManager as IMediaPosition;
            mc = (IMediaControl)graphManager;
            tsbtnPlay.Enabled = tsbtnPause.Enabled = tsbtnStop.Enabled = true;

            // Attach the view to the picture box (pbVideoDisplay) on frmMain.
            try
            {
                videoWindow = (IVideoWindow)graphManager;
                videoWindow.Owner = (int)pbVideoDisplay.Handle;
                videoWindow.WindowStyle = WS_CHILD | WS_CLIPCHILDREN;
                videoWindow.SetWindowPosition(
                pbVideoDisplay.ClientRectangle.Left,
                pbVideoDisplay.ClientRectangle.Top,
                pbVideoDisplay.ClientRectangle.Width,
                pbVideoDisplay.ClientRectangle.Height);
            }
            catch //(Exception Ex)
            {
                // I'll write code for this when I have a need to.
            }
            // Now we convert the video to a byte array.
            FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read);
            try
            {
                // Here we convert the video to Base 64.
                VideoInBytes = new byte[fs.Length];
                VideoInBytes = System.Text.Encoding.UTF8.GetBytes(ofd.FileName);
                VideoInBase64 = Convert.ToBase64String(VideoInBytes);
            }
            catch //(Exception Ex)
            {
                //throw new Exception("Error in base64Encode" + Ex.Message);
            }
        }
    }

Notice that I have code that converts the video to a Base64 string. This string will obviously have to be loaded into a memory stream. I'd like to add code that will allow me to play a video from a memory stream. Is that even possible with DirectShow and if so, what code would I need to add and where would I put it?


回答1:


The DirectShow way is to create a special so-called filter (source filter) that outputs video data and then add it to the graph chain.

Usually a filter is written in C++. Of course almost any code that can be written in C++ can be rewritten in C#. It could take a lot of work, for instance look at this article:

http://www.codeproject.com/Articles/421167/Pure-NET-DirectShow-Filters-in-Csharp

Another way is file emulation. In this case you would need 3rd party solution like BoxedApp.

The idea is to intercept some file functions like SetFilePointer and ReadFile, to provide data as it is written from a real file (but in fact it is read from memory).



来源:https://stackoverflow.com/questions/28844658/c-sharp-how-can-i-play-a-video-from-a-memory-stream-using-directshowquartz-dll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!