How to get Buffering Message to MainPage?

Jul 14, 2014 at 3:09 PM
Edited Jul 14, 2014 at 8:40 PM
I have some playlist's that are buffering and the image is frozen. In debugging mode there is a message like: Buffering 10% and so on.. How can I get this info to display it over the MediaElement?
If I handle like this:
private void mediaElement1_BufferingProgressChanged(object sender, RoutedEventArgs e)
        {
            if(mediaElement1.BufferingProgress<1)
            {
                progressbar.Visibility = System.Windows.Visibility.Visible;
                buffering.Visibility = System.Windows.Visibility.Visible;
                buffering.Text = "Buffering " + ((mediaElement1.BufferingProgress) * 100) + " %";
            }
            else
            {
                progressbar.Visibility = System.Windows.Visibility.Collapsed;
                buffering.Visibility = System.Windows.Visibility.Collapsed;
            }
        }
this does not work for me... in debug window there is buffering messages:
BufferingManager.UpdateBuffering: 69.21% duration 00:00:06.2293333 size 432526 starting False memory 3.50 MiB
Sample Video buffering 69.21%
TsMediaStreamSource.SignalHandler() re-requesting Audio, Video
BufferingManager.UpdateBuffering: 78.70% duration 00:00:07.0826667 size 492823 starting False memory 3.51 MiB
Sample Video buffering 78.70%
TsMediaStreamSource.SignalHandler() re-requesting Audio, Video
BufferingManager.UpdateBuffering: 87.70% duration 00:00:07.8933333 size 551695 starting False memory 3.76 MiB
Sample Video buffering 87.70%
TsMediaStreamSource.SignalHandler() re-requesting Audio, Video
BufferingManager.UpdateBuffering: 98.13% duration 00:00:08.8320000 size 609899 starting False memory 3.78 MiB
BufferingManager.UpdateBuffering done buffering: duration 00:00:09.2586667 size 638991 starting False memory 3.73 MiB
How can I get those messages to put them in my buffering text? Please henric if you have some time answer me.
Coordinator
Jul 14, 2014 at 9:26 PM
It's a little more complicated since the MediaElement can keep playing for a bit after phonesm's buffers run dry. There is some more info here: Why sometimes the image stops, but the sound is still normal play.
Jul 15, 2014 at 9:14 AM
henric wrote:
It's a little more complicated since the MediaElement can keep playing for a bit after phonesm's buffers run dry. There is some more info here: Why sometimes the image stops, but the sound is still normal play.
I know but why can we just get those messages from BufferingMenager.cs because they are here:
namespace SM.Media.Buffering
void UpdateBuffering(TimeSpan timestampDifference, int bufferSize)
        {
            if (_bufferingPolicy.IsDoneBuffering(timestampDifference, bufferSize, _totalBufferedStart, _isStarting))
            {
                _isBuffering = false;

                Debug.WriteLine("BufferingManager.UpdateBuffering done buffering: duration {0} size {1} starting {2} memory {3:F} MiB",
                    timestampDifference, bufferSize, _isStarting, GC.GetTotalMemory(false).BytesToMiB());

                DumpQueues();

                _isStarting = false;

                ReportBuffering(1);
            }
            else
            {
                var now = DateTime.UtcNow;

                var elapsed = now - _bufferStatusTimeUtc;

                if (elapsed >= BufferStatusUpdatePeriod)
                {
                    _bufferStatusTimeUtc = now;

                    var bufferingStatus = _bufferingPolicy.GetProgress(timestampDifference, bufferSize, _totalBufferedStart, _isStarting);

                    Debug.WriteLine("BufferingManager.UpdateBuffering: {0:F2}% duration {1} size {2} starting {3} memory {4:F} MiB",
                        bufferingStatus * 100, timestampDifference, bufferSize, _isStarting, GC.GetTotalMemory(false).BytesToMiB());
                    
                    ReportBuffering(bufferingStatus);
                }
            }
        }
Is there any possibilities to send that info to MainPage??
Coordinator
Jul 15, 2014 at 2:50 PM
Edited Jul 15, 2014 at 3:03 PM
The best way to get a hold of that is probably by modifying TsMediaStreamSource. If you look at TsMediaStreamSource.SendStreamSample, you can see where "source.BufferingProgress" is read. The "canCallReportBufferingProgress" only needs to prevent "ReportGetSampleProgress()" from being called; the fact that
the "var progress = source.BufferingProgress;" is inside the "if" clause is an optimization (no point in reading the value if you are not going to use it). Just be aware that "SendStreamSample()" is not running on the UI thread and I would strongly suggest avoiding any blocking calls from that thread.

If you are doing something along the lines of HlsView and are sampling the position anyway, then it may be easier to poll the BufferingProgress (add a property or method to TsMediaStreamSource). Per the other discussion, it may be both simpler and more reliable to poll the position and then consider things "Buffering" if the MediaElement.CurrentState is MediaElementState.Playing and multiple sequential position sample aren't increasing (you can always check to see if BufferingProgress.HasValue is true as well).
Jul 15, 2014 at 7:48 PM
Edited Jul 16, 2014 at 9:01 AM
henric thanks for your reply because I understand you don't have time for questions like this. I've tried today(after your reply) but I can't get it(stupid head or better low programming skills). So I beggin' you when you will take a cup of coffee take a look what i've done and say what's wrong.

So I added a property to TsMediaStreamSource:

I set it on
bool SendStreamSample(...)
{
...
if (canCallReportBufferingProgress)
                {
bufferstatus = source.BufferingProgress;
...
}
...
}

 public float? GetBufferStatus 
        {
            get { return bufferstatus; }
        }
Then I try to get it on my MainPage like this(I think here is the problem...):
void TsMediaManagerOnStateChange(object sender, TsMediaManagerStateEventArgs tsMediaManagerStateEventArgs)
        {
            ...
               TsMediaStreamSource buffer = new TsMediaStreamSource();
                                       if(mediaElement1.CurrentState == MediaElementState.Playing && buffer.GetBufferStatus !=0)
                                       {
                                          buffering.Text = "Buffering " + (buffer.GetBufferStatus) * 100;
                                       }
                                       
                                       UpdateState();
                                   });
        }
But I guess this will not update % every time % is rising...
It seems to me that I messed up things badly so if this is not even closer to what I need God damn it buffering stats. If you will ignore my message I will understand you.
Coordinator
Jul 16, 2014 at 10:02 PM
Edited Jul 16, 2014 at 10:55 PM
For that to work, you would need to get a hold of the same instance of TsMediaStreamSource that MediaElement is using. I think you would need to modify MediaStreamFacade to get a hold of it (add a property of type MediaStreamSource and set it to "mediaManager.MediaStreamSource" just before CreateMediaStreamSourceAsync() returns).

Something that might be simpler would be to modify HlsView.MainPage.OnPositionSamplerTick() such that the,
   if (positionSample == _previousPosition)
      return;
becomes something like,
   if (positionSample == _previousPosition)
   {
      if (MediaElementState.Playing == mediaElement1.CurrentState)
         ++_stuckCounter;
       else
          _stuckCounter = 0;

      UpdateBuffering();
   
      return;
   }

   if (0 != _stuckCounter)
   {
      _stuckCounter = 0;
      UpdateBuffering();
   }
Where "UpdateBuffering()" would need to do something like so:
   bool _isBuffering;
   int _stuckCount;

   void UpdateBuffering()
   {
      var shouldBuffer = _stuckCounter > 3;

      if (_isBuffering == shouldBuffer)
         return;

      _isBuffering = shouldBuffer;

      if (_isBuffering)
         DoSomethingToIndicateBufferingToTheUser();
      else
         DoSomethingToStopShowingBufferingToTheUser();
   }
I haven't tried this, but I suspect something like this might work for you.