IIS Smooth streaming low quality on start
Asked Answered
M

4

7

I m hosting some adaptive streaming video on windows azure and I have noticed that at the beginning the video start with the lowest avaiable bitrate. That is a big issue.

I have seen by searching the internet that a trick can be done by hooking the manifestready event and removing the lowest bitrates and then adding them back after some time. It make sense but I have seen no sample code of doing that.

I got the player code from expression encoder 4 and had a look but found nowhere where to do the change.

Does someone have more info on improving startup for smooth streaming?

Thank you very much

Manometer answered 25/8, 2011 at 11:42 Comment(0)
M
7

Hello I posted the question to the Media Platform Player forum and got an answer that works.

The discussion is here: http://smf.codeplex.com/discussions/271042

Here is the code I use:

public MainPage() {
        InitializeComponent();
        player.MediaPluginRegistered += new EventHandler<CustomEventArgs<IMediaPlugin>>(player_MediaPluginRegistered);
        player.PlayStateChanged += new EventHandler<CustomEventArgs<MediaPluginState>>(Player_PlayStateChanged);
    }
private IAdaptiveMediaPlugin _adaptivePlugin = null;
private bool isStartupHeuristicsActive = false;

void player_MediaPluginRegistered(object sender, CustomEventArgs<IMediaPlugin> e) {
    var adaptivePlugin = e.Value as IAdaptiveMediaPlugin;
    if (adaptivePlugin == null) return; 
    if (_adaptivePlugin == null) _adaptivePlugin = adaptivePlugin;
    _adaptivePlugin.ManifestReady +=new Action<IAdaptiveMediaPlugin>(_adaptivePlugin_ManifestReady);
}

void  _adaptivePlugin_ManifestReady(IAdaptiveMediaPlugin obj)
{
    if (_adaptivePlugin != null)
    {
        var videoStream = _adaptivePlugin.CurrentSegment.SelectedStreams.Where(i => i.Type == StreamType.Video).FirstOrDefault();

        if (videoStream != null)
        {
            var averageBitrate = videoStream.AvailableTracks.Average(t => t.Bitrate);

            var track = videoStream.AvailableTracks.FirstOrDefault(t => t.Bitrate >= averageBitrate);
            if (track != null)
            {
                isStartupHeuristicsActive = true;
                videoStream.SetSelectedTracks(new[] { track });
            }
        }
    }
}

private void Player_PlayStateChanged(object sender, CustomEventArgs<MediaPluginState> e)
{
    if (isStartupHeuristicsActive && e.Value == MediaPluginState.Playing)
    {
        isStartupHeuristicsActive = false;
        if (_adaptivePlugin != null)
        {
            var videoStream = _adaptivePlugin.CurrentSegment.SelectedStreams.Where(i => i.Type == StreamType.Video).FirstOrDefault();
            if (videoStream != null)
            {
                videoStream.SetSelectedTracks(videoStream.AvailableTracks);
            }
        }
    }
}

Thank you

Manometer answered 5/9, 2011 at 12:26 Comment(0)
M
4

As the other answer mentioned, use MMPPF (previously Silverlight Media Framework). Much more full-featured player and relatively easy to customize (with video tutorials, too).

For the bitrate - yes, the Smooth Streaming algorithm is designed for the lowest latency start possible - therefore, lowest bitrate/video chunk is used on start. However, it is possible to do what you want.

You will need to do 2 things, first:

Add a handler to the player's OnMediaPluginRegistered event. In that event, check to see if it's an IAdaptiveMediaPlugin - you'll need the instance of that plugin. Here's a sample...

    IAdaptiveMediaPlugin _adaptivePlugin = null;

    void OnMediaPluginRegistered(object sender, Microsoft.SilverlightMediaFramework.Core.CustomEventArgs<Microsoft.SilverlightMediaFramework.Plugins.IMediaPlugin> e)
    {
        var adaptivePlugin = e.Value as IAdaptiveMediaPlugin;

        if (adaptivePlugin == null) { return; }

        if (_adaptivePlugin == null)
        {
            _adaptivePlugin = adaptivePlugin;
        }
    }

Once you have that, wait for one of the media open events to fire (MediaOpened or something), and you will now have access to a method on IAdaptiveMediaPlugin called SetVideoBitrateRange(...).

For example:

_adaptivePlugin.SetVideoBitrateRange(minBitrate, maxBitrate, true);

That should give you what you need.

Mozellamozelle answered 25/8, 2011 at 16:9 Comment(1)
Hello, thank you for the answer. I have switched to MMPPF and it seems to be much more customisable and featured. How ever I tried this : void player_MediaOpened(object sender, EventArgs e) { var maximumPossibleBitrate = player.AvailableVideoBitrates.Max(); _adaptivePlugin.SetVideoBitrateRange(maximumPossibleBitrate, maximumPossibleBitrate, true); } And the first 3s are stile not good but then it use the range. So it's stile an issue at the begining. Should I clear the buffer or something? Thank youManometer
M
0

Try using the Microsoft Media Platform: Player Framework instead of the Expression Encoder Player - it has more advanced logic.

Mesic answered 25/8, 2011 at 14:56 Comment(1)
Thank you, this player is indeed much more advancedManometer
C
0

you can remove the extra streams (the low quality ones) at the server side either by hand (need to edit the xml files there, not just remove the physical stream files), or use IIS which provides facility to edit smooth streams (assuming you installed respective extension, say via Microsoft Platform installer app). Also you can use WinMerge or similar tool to compare a copy of the clip's folder you kept before using MS tool to see what it changes when you remove a specific (sub)stream from a smooth stream (compare the previous and the new version of the .ism* files)

that is also useful cause sometimes the player underestimates the client CPU and bandwidth (there are some custom versions available that are supposed to fix CPU heuristics issue, by having some config file pre-edited appropriately). That is if you have some screencast, sometimes client don't get stream of enough quality to read the text, so you have to remove lower quality (sub)streams and then it plays fine (you start removing the lower ones and see after which one it shows OK). You can also configure the TransformManager (or your code that calls into the respective functionality) to not create very low quality versions

Correy answered 25/1, 2014 at 19:6 Comment(3)
I'd certainly like it to fall-back onto the lower quality streams, but be able to set that it starts on a higher bit-rate.Terat
There's also another thing called CPU Heuristics. For lower CPUs, Expression Encoder templates had issue and generated configuration that underestimates the CPU and thus starts from even worse quality that it could if I remember well what the issue was. See blog.axinom.com/2012/02/02/… , social.expression.microsoft.com/Forums/en/encoder/thread/… and blogs.msdn.com/b/randyoakley/archive/2010/09/06/… for more infoCorrey
regarding the config.xml file seeked by SSME (Smooth Streaming Media Element) see forums.iis.net/t/… and on how to use it with SMF-based solutions (which uses SSME under the hood), see smf.codeplex.com/discussions/552388Correy

© 2022 - 2024 — McMap. All rights reserved.