Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Media Stream Tester

, 16 Oct 2008
Rate this:
Please Sign up or sign in to vote.
In this article I will tell you about one of the most important components of channels check system

Introduction

Working on sites of online television we, as a KB_Soft Group team faced a task of checking channels relevance, which were offered by site visitors for viewing. It is great when there are several thousands of channels on the site and a convenient access to these channels is offered. But it is bad that a half of these channels are invalid. In order to be sure that site visitors are offered actually valid channels for viewing, we needed to make a check of channel states on a regular basis. And it would be nice if such a check would be made automatically — without participation from a human.

Thus, a task of a regular check of channels relevance was formed. In this article I will tell you about one of the most important components of channels check system — StreamChecker.

This is a module, which checks the state of a specified Media Stream. Media Stream Tester is a small application for testing StreamChecker functionality. Media Stream Tester is completely ready to use. If you want a simple instrument for checking Media Streams, then Media Stream Tester is exactly what you need. If you need to get information about Media Stream and carry out a custom processing, then you can use the StreamChecker class in your application. Media Stream source code will serve a good example of how to use the StreamChecker class, and this article will allow you to understand how this class works.

Background

Media Streams can be different and that is why a “head-on” decision — to write a module, which will connect itself with the stream and check its state, is too laborious. We looked at the task from another point of view — it is required to be able to check the channels which can be played back by a player used by the site (this player is Windows Media Player ®). And we decided that the best way to check the stream is to try to play it back in Windows Media Player ®.

This is how we decided to make it:

  • Create an instance of Windows Media Player object (invisible and soundless)
  • Give it a command to open and played back Media Stream
  • Wait for some time for the stream to open and playback
  • Collect maximum of data about a stream
  • Close the stream

In order to work with Windows Media Player it is needed to add to assembly a COM reference to Windows Media Player (WMPLib).

  1. Creating of instance of Windows Media Player is simple:
    WMPLib.WindowsMediaPlayer player = new WMPLib.WindowsMediaPlayer ();
                
    player.settings.mute = true;	//switch off a sound
    
    AutoResetEvent waitEvent = new AutoResetEvent (false);
    
    CheckResult result = new CheckResult ();
    
    player.PlayStateChange += new 
    	WMPLib._WMPOCXEvents_PlayStateChangeEventHandler(
    	    player_PlayStateChange);

    The last string of the code is subscribed for an event “state of stream playback changed” in order to be able to know that the stream started to playback. Below, you will see this method code. As soon as the playback started, we set an event in order to abort playback waiting:

    void player_PlayStateChange (int NewState)
    {
        try
        {
            switch (NewState)
            {
                case 3: // The current media item is playing.
    
                    scanResult.isOnline = true;
                    waitEvent.Set ();
                    break;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show (ex.Message);
        }
    }
  2. This is how to open and playback the stream:
    player.settings.autoStart = true;
    player.URL = streamURL;
  3. Stream opening and playback waiting looks like that:
    //
    // We are waiting for the start of playback for 10 seconds.
    //
    TimeSpan openTimeout = TimeSpan.FromSeconds (10);
    int openTimeout = 20;
    bool waitResult = waitEvent.WaitOne (openTimeout, false);
    
    //
    // It was impossible to play the stream back.
    //
    if (!waitResult) return result; 
    
    //
    // Playingback the stream for 30 seconds, in order to collect statistic.
    //
    TimeSpan readTimeout = TimeSpan.FromSeconds (30);
    Thread.Sleep (readTimeout);
  4. The following data are received about the stream:
    //
    // Bandwidth.
    //
    canResult.bandWidth = player.network.bandWidth;
    
    //
    // Bitrate.
    //
    scanResult.bitRate = player.network.bitRate;
    
    //
    // The frameRate property retrieves the current video frame rate in 
    // frames per hundred seconds. For example, a value of 2998 indicates 
    // 29.98 frames per second.
    //
    scanResult.frameRate = player.network.frameRate;
    
    //
    // The encodedFrameRate property retrieves the video frame rate 
    // specified by the content author in frames per second
    //
    scanResult.encodedFrameRate = player.network.encodedFrameRate;
    
    //
    // The framesSkipped property retrieves the total number of frames 
    // skipped during playback.
    //
    scanResult.framesSkipped = player.network.framesSkipped;
    
    //
    // The receivedPackets property retrieves the number of packets received.
    //
    scanResult.receivedPackets = player.network.receivedPackets;
    
    //
    // The recoveredPackets property retrieves the number of recovered 
    // packets.
    //
    scanResult.recoveredPackets = player.network.recoveredPackets;
    
    //
    // The lostPackets property retrieves the number of packets lost.
    //
    scanResult.lostPackets = player.network.lostPackets;
    
    //
    // The receptionQuality property retrieves the percentage of packets 
    // received in the last 30 seconds.
    //
    scanResult.receptionQuality = player.network.receptionQuality;
    
    //
    // The sourceProtocol property retrieves the source protocol used to 
    // receive data.
    //
    scanResult.sourceProtocol = player.network.sourceProtocol;
    
    //
    // The imageSourceHeight property retrieves the height of the current 
    // media item in pixels.
    //
    scanResult.imageSourceWidth = player.currentMedia.imageSourceWidth;
    
    //
    // The imageSourceWidth property retrieves the width of the current 
    // media item in pixels.
    //
    scanResult.imageSourceHeight = player.currentMedia.imageSourceHeight;
  5. The stream is closing like that:
    player.close ();

Comments to Use

This method presupposes interacting with the User's desktop, that is why it is unsuitable for use in services. It is necessary that a message handling loop would be in the application. Also, it was discovered during testing, that simultaneous scanning of several stream causes fatal errors in Media Player. That is why it is advisable to refuse multithreaded channel checks.

References

  • This page contains the latest version of this article and the C# implementation of the class described in the article.

History

  • 15 October, 2008 -- Original version posted.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Alexandr Golovanov
Web Developer
Russian Federation Russian Federation
Alexandr Golovanov is a .NET developer at KB_Soft Group, an offshore software development company located in Russia, Novosibirsk. Here he has worked
on various .NET projects.

Comments and Discussions

 
GeneralMy vote of 2 PinmemberKOUKKILLER15-Sep-12 21:54 
QuestionHi (advice) PinmemberKOUKKILLER15-Sep-12 21:54 
GeneralMedia player 9 codec missing PinmemberRebeccaLim23-Jul-09 22:48 
Generalспасибо; благодарю вас PinmemberJamal Alqabandi21-Oct-08 2:45 
GeneralRe: спасибо; благодарю вас Pinmembergoodkoal2-Aug-09 17:56 
GeneralRe: спасибо; благодарю вас PinmemberJamal Alqabandi10-Aug-09 1:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 16 Oct 2008
Article Copyright 2008 by Alexandr Golovanov
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid