views:

1617

answers:

6

Using NetStream to stream content from http, I've noticed that esp with certain exported h264's, if the player encounters an empty buffer, it will stop and buffer to the requested length (as expected).

However once the buffer is full, the playback doesn't resume, but instead jumps ahead, as such- instantly playing the buffered duration in a brief moment, and thusly triggering an empty buffer again.. this will then continue over and over.

Presumably when the netstream pauses to buffer, the playhead position continues, and the player is attempting to snap to that position on resume- however given it could take 5 seconds to build a 2 second buffer- it ends up with a useless buffer again..

(this is an assumption)

I've attempted to work around this by listening for an empty buffer netstatus event, pausing the stream, and at the same time setting up a loop to check the current buffer length vs the requested buffer length.. and resuming once the buffer length is greater than or equal to the requested buffer.. however this causes problems when there isn't enough of the video remaining.. for example, a 10 second buffer with only 5 seconds remaining, the loop just sits there waiting for a buffer length of 10 seconds when theres only 5 left...

You would think that you could simply check which was smaller, the time left or the requested buffer length.. however the times flash gives are not accurate..

If you add the net streams current time index, plus the buffered time, the total is not the entire duration of the movie (when at the end).. it is close but not the same.

This brings me back to the original problem, and if there is another way to fix this, clearly flash knows when the buffer is ready, so how can i get flash pause when it buffers, and resume once the buffer is ready? currently it doesn't.. it pauses and then once the buffer is full- it plays the entire buffered content in about .1 of a second.

Thanks in advance, Stephen.

A: 

I never encountered the problem you described. Does it happen on every video?

One thing you can try is streaming your video with JW Player to see if the same problem happens (http://www.longtailvideo.com/players/jw-flv-player/). This is an open source video player built in AS3.

David
Hi David, no it doesn't happen on every video- so presumably its an encoding problem.. which is a nightmare. It's encoded as h264 from camtasia, keyframes every second.. I think I'll try a few different exports to try and nail the problem- if I find it I'll post back. Thanks
meandmycode
+1  A: 

Alright well, plenty of searching around (wow, how hard is it to describe this problem).. I guess additionally the problem is related to lower bandwidth and a lot of people may not test this scenario..

So anyway, plenty of people experiencing this issue- seems dependant on the codec settings- perhaps keyframing or how the streaming hints work.. I've no idea.

What I do know is this shouldn't be a concern to the player, flash yet again becomes a huge let down..

BUT, I did manage to make a hack to resolve this issue, if you listen to the netstatus event, and wait for an empty buffer event, you pause the stream.. ideally now you listen for a buffer full event, and resume it- but since the stream is paused- the buffer doesn't build (but of course, the video is still being loaded in).

If you now set a timer (I set an event on enter frame), and listen for one of two conditions to become true:

  • a) the bufferLength is greater than or equal to the bufferTime (actual buffer is at least requested buffer size)
  • b) the loaded bytes count equals the total bytes count

Condition A isn't enough because at the end of the video, the bufferLength may not be able to fit the requested buffer size because the time remaining is less, and checking the current playhead location + actual buffer length at this time does not equal the duration of the movie, so this is why condition B is needed, you check that the actual movie is completely loaded, and as such playable.

Here's my code if at all useful to anyone:

function onNetStatus(e:NetStatusEvent):void

    if (e.info.code == "NetStream.Buffer.Empty") {

     ns.pause();

     playerRoot.addEventListener(Event.ENTER_FRAME, function() { 
      if (ns.bufferLength >= ns.bufferTime || ns.bytesLoaded == ns.bytesTotal) {
       playerRoot.removeEventListener(Event.ENTER_FRAME, arguments.callee);
       ns.resume();
      }
     });
    }
}

Cheers.

meandmycode
A: 

I am experiencing the problem repeatedly. The problem is the NetStream object reports the wrong value for bufferLength property. I think it's a bug.

Below is a typical dump of my bufferLength property at 1 second intervals. Note the jump from 5.987 to 37.95 after the first "Buffer empty" event. As I've set a 20 sec buffer, the NetStream object properly fires the Buffer full message. Note the subsequent correction shortly thereafter from 46.794 to 5.374. This explains the "quick" buffer empty event as the buffer never filled.

I've got one of these "oh my god" moments here. Have important live broadcasts coming up and this is one hell of a bug. If there's anybody out there with helpful insight it would be greatly appreciated.

4.854
4.538
4.248
3.815
3.545
3.249
3.051
2.503
1.851
1.242
0.581
Buffer empty:
0.423
0.919
1.768
2.591
3.374
4.21
5.151
5.987
Buffer full:
37.95
47.596
47.346
47.251
46.922
46.731
46.794
5.374
5.098
4.429
3.95
3.334
2.979
2.441
2.093
1.869
1.514
1.479
1.228
0.88
0.577
0.483
Buffer empty:
0.521
1.148
2.062
2.536
3.264
3.917
4.753
5.572
6.268
7.182
8.018
8.75
9.638
10.395
10.657
11.101
11.611
12.172
12.694
13.4
13.922
14.81
15.568
16.45
17.266
17.971
18.676
19.512
Buffer full:

Robert
A: 

It's my network at the office. It's corrupting data before it reaches the video player. The player uses this bad data and improperly calculates the current buffer size. But read on. Real good read for live streaming people.

I've been doing extensive testing and observing. You know, playing and encoding from different locations. I get the problem repeatedly while playing the video at my office (dual T1's) no matter where I encode from, my office or offsite. I don't get it if I PLAY the video from home on a cable connection or on an AIR card in a laptop; again, no matter the encoding location. I can run for an hour at a ridiculously high bitrate (like 2000kbps). I do not get the bad bufferLength data problem once. The player obviously struggles to keep up with the high data rate but it functions properly. It plays through it's buffered data completely, stops, rebuffers completely, plays and repeats the cycle. At the really high data rate I can rebuffer say 90 times in 60 mins. Never get bad bufferLength data values.

Playing at the office, I repeatedly get bad data values like those listed in this post.

Obviously not a Flash bug. It's bad data reaching the player.

Would love to know the exact anatomy of the problem.

Not an expert but I imagine the player has to calculate the data it thinks is in the buffer based on metadata contained within the live stream. Maybe things like frames per second and resolution and such. Somehow it must get bad values for these things. How? From the stream source - FMS? Not likely. From the same FMS source I get no data errors at the player if I play from home or on an AIR card. So it's the network at my office because it happens on all machines there.

Easy to say well the network has a poor design or faulty switches or routers, but what specifically about that causes the bad data values in the live stream. Is it corrupted packets or lost packets? Would love to know the exact anatomy there.

Robert
A: 

Turns out this IS NOT my network. I'm experiencing the problem offsite and on 3G cards as well.

I really don't understand it. How can anything I do in my application cause the bufferLengh property to contain the wrong value? I have definitely demonstrated that the numbers returned are wrong. When buffering up and checking the time in the buffer every second, the numbers 37.95-46.794 at the bottom of this post are definitely wrong. This must be a bug.

I wish someone from Adobe woul respond to this issue. It is wrecking playback. I enter repeated buffering cycles because the buffer never fills to the 20 seconds I've set it to. The false values are killing the playback functionality.

I was under the impression that when I play my live stream, and set a bufferTime property of 20 seconds on the NetStream, that it would buffer that full amount before playing. What am I doing wrong? Doesn't seem like there is much to it. Set the NetStream bufferTime property to 20, like so,

ns.bufferTime = 20;

And playback should wait until 20 seconds worth of data are in the buffer before playback occurs. How can I screw this up?

Buffer empty:
0.423
0.919
1.768
2.591
3.374
4.21
5.151
5.987
Buffer full:
37.95
47.596
47.346
47.251
46.922
46.731
46.794
5.374
5.098
4.429
3.95
3.334

Robert
A: 

Any solution, man ? This is annoying !!!

thienhaflash