IIS Smooth streaming low quality on start

2019-02-06 23:45发布

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

4条回答
We Are One
2楼-- · 2019-02-07 00:30

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

查看更多
迷人小祖宗
3楼-- · 2019-02-07 00:42

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

查看更多
混吃等死
4楼-- · 2019-02-07 00:48

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.

查看更多
一夜七次
5楼-- · 2019-02-07 00:49

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

查看更多
登录 后发表回答