Menu

video streaming server-client program in c#

john
2008-10-02
2012-10-29
  • john

    john - 2008-10-02

    hello,
    i am currently developing a server-client program using directshow in c#.
    I have already done a player that can render a media stream in the web.
    for example: mms://winmedia.itsc.cuhk.edu.hk/cuhk/cuhk_xb5.wmv
    I have build a filter graph, adding the source filter and let the intelligent graph builder to complete the filer graph. The program can render the file.
    What I want to do next is to modify this program as a server to receive the same stream but not render it. I would like to transport the stream over TCP/IP connection to the client side and render it.

    I got the problem when choosing a pair of filter, one can transport the original media stream over TCP/IP without encoding/decoding and another one can receive the stream respectively. does anyone know any filter in Direcrshow library that can perform this work?

    here's my sample code of my filtergraph:

    void BuildGraph(IGraphBuilder pGraph, string srcfile1)
    {
    int hr = 0;

            ICaptureGraphBuilder2 pbuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
            hr = pbuilder.SetFiltergraph(pGraph);
            checkHR(hr, "Can't Set FilterGraph");
    
            Guid clsid_WindowsMediasourcefilter = new Guid("{6B6D0800-9ADA-11D0-A520-00A0D10129C0}");
            //add source filter
            IBaseFilter pWindowsMediasourcefilter = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(clsid_WindowsMediasourcefilter));
            hr = pGraph.AddFilter(pWindowsMediasourcefilter, "source filter)");
            checkHR(hr, "Can't add source to graph");
    
            Graph.AddSourceFilter(srcfile1, srcfile1, out pWindowsMediasourcefilter);
            pGraph.RenderFile(srcfile1, null);        
        }
    
     
    • almere109

      almere109 - 2008-11-27

      I think a combination of calls, starting with SetOutputFilename (or something like that) specifying the proper file save format. Then it might be needed to initialize the file writer with the proper profile too. Then the required RenderStreams can be called.
      In my code example these steps can be found. The special thing of the code example is the check whether audio/video is supported. So the information is available which streams can be connected to the file writer.

       
    • snarfle

      snarfle - 2008-10-02

      I have never used the NetShowSource filter, so I really don't know much about it. I don't believe MS includes any such filters when they ship the OS (http://msdn.microsoft.com/en-us/library/ms783348(VS.85).aspx).

      I'm not clear on your requirement about "without encoding/decoding".

       
    • john

      john - 2008-10-02

      "without encoding/decoding" ...
      I may explain like this: the server receive the video stream form "mms://......." and then act as a repeater to transmit/forward the received stream to the client side without any video processing

       
      • snarfle

        snarfle - 2008-10-02

        Not an area I'm very familiar with. Doesn't seem like you'd need DirectShow to do this, however.

        You might experiment with some of the samples from http://windowsmedianet.sourceforge.net. The AsfNet sample has some code that sets up a server. And the AudioPlayer sample shows how to retrieve the data. Playing with http://msdn.microsoft.com/en-us/library/aa389172(VS.85).aspx should help get the uncompressed data.

        It won't be easy. These samples may point the way, but in the end, you'll be writing mostly from scratch.

         
    • Zhutik

      Zhutik - 2008-11-21

      After reading this branch, i start my experiment with creating streaming server and client.
      First i start working with my web cams and successfully complete this part - so i have server, which cam stream video and audio from my capture devices and configure format of the output (WMSysPr9.prx)
      This is part of code (part of AsfNet Sample, from WindowsMediaLib V1-0 ):

                  hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter);
                  DsError.ThrowExceptionForHR( hr );
      
                  asfWriter = ConfigAsf(capGraph, szFileName);
                  DoAnet(asfWriter);
      
                  hr = m_graphBuilder.AddFilter( capFilter, "Ds.NET Video Capture Device" );
                  DsError.ThrowExceptionForHR( hr );
      
                  hr = m_graphBuilder.AddFilter(audio, " Audio"); // audio = CreateFilter(FilterCategory.AudioInputDevice, audio_device_name);
                  DsError.ThrowExceptionForHR(hr);
                  hr = capGraph.RenderStream(null, null, capFilter, null, asfWriter);
                  DsError.ThrowExceptionForHR( hr );
      
                  hr = capGraph.RenderStream(null, null, audio, null, asfWriter);
                  DsError.ThrowExceptionForHR(hr);
      

      Works fine. My question is: how can i modify this code to stream video files?
      I do some job, but stick in streaming audio from this file.
      i change this section hr = m_graphBuilder.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter);
      for hr = m_graphBuilder.AddSourceFilter(filename, filename, out capFilter);
      DsError.ThrowExceptionForHR( hr );
      But i have no audio from my file.

      if i use m_graphBuilder.RenderFile(filename, null) , i cant stream at all, cause i cant configure capFilter for streaming.
      It would be very nice, if someone can help me deal with... thanks

       
      • snarfle

        snarfle - 2008-11-23

        Which profile from WMSysPr9 are you using? Not all profiles have audio components. Quoting from one of the readmes:


        Probably the most common question about this sample is how to change the format of the output (ie other than "No audio, 56 Kbps". The easy answer is to say "use one of the other formats in %windir%\WMSysPr9.prx". Unfortunately there aren't very many formats in that file that don't have audio.

        The other answer is to suggest that you read the WMF docs about IWMProfileManager::LoadProfileByData. You can generate profiles for that method using a tool from MS's WMF sdk named GenProfile.

        Also, the most current AsfNet sample is in http://WindowsMediaNet.SourceForge.Net

         
    • almere109

      almere109 - 2008-11-22

      The ASF file writer can be configured as network server. The should be a C# code example Asfnet for that, have a look at http://directshownet.cvs.sourceforge.net/viewvc/directshownet/windowsmedialib/samples
      Some time ago, I got the server part working. I did not had time to do the same for the client. But there a C++ code example that shows how that can be done.

       
    • almere109

      almere109 - 2008-11-23

      Adding Video goes the same way as WMV file saving. For finding a suitable profile, the profile can be checked. My codeproject video filesaving article explains how both can be done, there is also a code example with it. This can be found at http://www.codeproject.com/KB/audio-video/videosav.aspx

       
    • Zhutik

      Zhutik - 2008-11-24

      I'm not very good English speaker, so i think my previous message was not clear.

      TO qf3lnfsLd: now i try to stream video to my clients (the way i wanna do this - is like AsfNet sample do it ). Source - is video file from my PC (video file with audio). My WMSysPr9 profile - Windows Media Video 8 for Local Area Network (256 Kbps).
      How i try to do this:
      capGraph = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

                  hr = capGraph.SetFiltergraph( m_graphBuilder );
                  DsError.ThrowExceptionForHR( hr );
      
                  hr = m_graphBuilder.AddSourceFilter(filename,filename, out capFilter);
                  DsError.ThrowExceptionForHR( hr );
      
                  asfWriter = ConfigAsf(capGraph, szFileName);
                  DoAnet(asfWriter);
      
                  hr = m_graphBuilder.AddFilter( capFilter, "Ds.NET Video Capture Device" );
                  DsError.ThrowExceptionForHR( hr );
      
                  hr = capGraph.RenderStream(null, null, capFilter, null, asfWriter);
                  DsError.ThrowExceptionForHR( hr );
      
                  m_mediaCtrl = m_graphBuilder as IMediaControl;
      

      and when i start my media control i get an error: hr = -2147467259 (using Windows Media Video 8 for Local Area Network (256 Kbps))

      when i switch to Windows Media Video 8 for Dial-up Modem (No audio, 56 Kbps) profile. works fine.
      I think the problem is to play audio from this file. Could you help me with this?

      TO almere109: Thanks, you did great job. But my problem is to stream my video files over my lan.

       
      • snarfle

        snarfle - 2008-11-26

        If you are using a profile that includes sound, but you don't have the sound actually hooked up to the WM Writer, you will get an error. Could that be your problem?

         
    • Zhutik

      Zhutik - 2008-11-26

      Yes, this is it! So my question is how hook up sound to WM Writter?
      m_graphBuilder.AddSourceFilter(filename, filename, out capFilter) adding only video.

       
      • snarfle

        snarfle - 2008-11-27

        When add call "AddSourceFilter", it is probably adding a filter with two output pins (assuming the file you are adding has audio). Your later calls (perhaps using RenderStream?) needs to connect both pins, probably necessitating two RenderStream calls.

         
    • almere109

      almere109 - 2008-11-26

      In my code I use something like this:
      cat = PinCategory.Capture;
      med = MediaType.Audio;
      hr= captureGraphBuilder.RenderStream(cat, med, AudioDeviceFilter, null, asfMuxFilter);

      cat = PinCategory.Capture;
      med = MediaType.Video;
      hr= captureGraphBuilder.RenderStream(cat, med, VideoDeviceFilter, null, asfMuxFilter);

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.