http-streaming icon indicating copy to clipboard operation
http-streaming copied to clipboard

Not starting on first segment

Open ghost opened this issue 6 years ago • 11 comments

campones commented on Oct 25, 2017, 7:39 PM UTC:

Hi there

I m using last cdn version of both videojs and video-contrib-hls provided here.

I m looking to upgrade from the "old" hls.js from Guillaume with a more recent version of the script.

But when I compare the 2 setup, I notice videojs-contrib-hls need to download 2 segments to start playing while the hls.js script along with the benjipot integration for videojs need only one. That means, users need to wait double time to actually see a video starting.

Is there any settings I can use with videojs-contrib-hls to have the player starting after the first segment is downloaded?

thanks

This issue was moved by forbesjo from videojs/videojs-contrib-hls#1285.

ghost avatar Jul 02 '18 19:07 ghost

mjneil commented on Oct 25, 2017, 8:43 PM UTC:

Hi campones

The player should start playing after the first segment has downloaded. The only scenarios I can think of that would require 2 segments to be downloaded before playback are if the audio and video are demuxed, i.e. in separate streams, both an audio and a video segment need to be downloaded before starting. The other case is if you are playing a live stream in IE11 on windows 8.1 or 10 because of an issue with seeking before the tech is ready in IE11.

If these scenarios are not what you are doing, it sounds like it could be a bug, but hard to say without an example. Would you be able to provided a code example or source?

ghost avatar Jul 02 '18 19:07 ghost

campones commented on Oct 25, 2017, 9:29 PM UTC:

no sorry but the segment contains both audio and video.

I tested in last chrome win7 x64

ghost avatar Jul 02 '18 19:07 ghost

campones commented on Oct 29, 2017, 11:41 PM UTC:

actually it is funny.. I have been switching to another stream type, pseudo live, meaning those are pre-encoded files with ffmpeg that I stream, and not real live streaming that I restream ,and then it starts on first segment. So one possible reason would be the metadata?

Still the hls.js library along with the benji-pot videojs integration is able to play those real live streams after downloading one segment, unlike videojs-contrib-hsl

ghost avatar Jul 02 '18 19:07 ghost

campones commented on Oct 30, 2017, 12:01 AM UTC:

so yea, taking that into account I just tried restreaming a live stream but this time, reencoding also the video track, using libx264 , and indeed videojs-contrib is able to display the video after the first segment.

Obviously usually, I never encode the video track since this is very cpu consuming and not necessary with hls.js

/usr/local/bin/ffmpeg -re -i pipe:0 -c:v libx264 -c:a libfdk_aac -f flv will work on first segment

/usr/local/bin/ffmpeg -re -i pipe:0 -c:v copy -c:a libfdk_aac -f flv will need to download 2 segments to start.

This is rather surprising since the original video track is anyway in h264 codec video, but native as per ffmpeg

Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264)) Stream #0:1 -> #0:1 (aac (native) -> aac (libfdk_aac))

ghost avatar Jul 02 '18 19:07 ghost

campones commented on Oct 30, 2017, 12:30 AM UTC:

I did a little media info on both segment

videojs-contrib need 2 segments

General
ID                                       : 1 (0x1)
Complete name                            : D:\Downloads\test1-3.ts
Format                                   : MPEG-TS
File size                                : 8.60 MiB
Duration                                 : 18 s 0 ms
Overall bit rate mode                    : Variable
Overall bit rate                         : 3 642 kb/s

Video
ID                                       : 256 (0x100)
Menu ID                                  : 1 (0x1)
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : [email protected]
Format settings, CABAC                   : Yes
Format settings, ReFrames                : 3 frames
Codec ID                                 : 27
Duration                                 : 20 s 0 ms
Bit rate mode                            : Variable
Maximum bit rate                         : 3 303 kb/s
Width                                    : 1 280 pixels
Height                                   : 720 pixels
Display aspect ratio                     : 16:9
Frame rate                               : 25.000 FPS
Standard                                 : Component
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Color range                              : Limited
Color primaries                          : BT.709
Transfer characteristics                 : BT.709
Matrix coefficients                      : BT.709

videojs-contrib need only 1 segment:

General
ID                                       : 1 (0x1)
Complete name                            : D:\Downloads\test1-25.ts
Format                                   : MPEG-TS
File size                                : 3.79 MiB
Duration                                 : 18 s 280 ms
Overall bit rate mode                    : Variable
Overall bit rate                         : 1 228 kb/s

Video
ID                                       : 256 (0x100)
Menu ID                                  : 1 (0x1)
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : [email protected]
Format settings, CABAC                   : Yes
Format settings, ReFrames                : 4 frames
Codec ID                                 : 27
Duration                                 : 23 s 520 ms
Width                                    : 1 280 pixels
Height                                   : 720 pixels
Display aspect ratio                     : 16:9
Frame rate mode                          : Variable
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive

not sure why the difference but maybe you do

ghost avatar Jul 02 '18 19:07 ghost

campones commented on Jan 28, 2018, 5:26 PM UTC:

follow up..

ghost avatar Jul 02 '18 19:07 ghost

mjneil commented on Jan 29, 2018, 5:10 PM UTC:

Hi campones sorry for letting this go unnoticed for so long, I did not see your updates after my last response. Based on the information you provided, I'm not quite sure why this issue is happening. Would you be able to provide both streams or 2 consecutive segments from both (with and without the video being re-encoded) so that I can take a closer look?

ghost avatar Jul 02 '18 19:07 ghost

campones commented on Jan 29, 2018, 5:28 PM UTC:

hi,

for example this live stream need 2 (or even 3) segments on chrome to start https://goo.gl/eQ4GKz

this other live stream (pseudo live already reencoded with ffmpeg) needs only one segment https://goo.gl/xokSb1

ghost avatar Jul 02 '18 19:07 ghost

mjneil commented on Jan 30, 2018, 9:26 PM UTC:

Thanks for providing the sources campones

So it looks like in the case where 2 segments are needed, the playlist has a window of 4 segments each with duration 20s, and a target duration of 20s. Apple specifies that last segment duration + 2 * target duration is unsafe for smooth playback, so the player calculates the seekable range to be 0-20s. On playback start, the player seeks to the end of the seekable range to start as close to the live edge as possible. Because this is right at the segment boundary, the player ends up requesting the first segment (this is because the segment fetching logic around segment boundaries is conservative to simplify things), which is actually roughly 19.8s (this is ok, manifest durations are not required to be perfectly accurate), but because the player is trying to play content at 20 seconds, it requires the next segment to get started.

The other stream also has a window of 4 segments, but the target duration differs, and segment durations are not all the same. This seems to cause seekable range to be calculated as 0-0s, so when seeking to the live point at play start, its just a seek to 0, and the player is able to play once the first segment is downloaded at content is buffered at 0.

I can’t imagine you are the only one experiencing this issue, so it is something I’d like to address at some point. However it is a more complicated problem in practice than it seems on paper, so I don’t expect any solutions in the short term.

I can provide some suggestions to help avoid the issue. My first suggestion would be to encode the video track like you do the second stream. While I understand that it is very CPU intensive, it provides other benefits to yourself and viewers. The segments in the first stream are over twice the size of the files in the second stream. Even with a very fast connection, some segments take longer than their duration for me to download. This will lead to repeated stalling and buffering, as well as much slower startup times (which becomes an even bigger problem when combined with the issue you reported here). Encoding the video track will reduce bandwidth consumption and improve overall playback experience. If this just isn’t an option, another thing you can try is to segment the stream more. The 20 second segments produce large files that are required to be downloaded in full before playback can begin. Apple recommends segments with a duration of 6 seconds. If you can segment at a smaller interval such as 6s, file sizes will be reduced and hopefully improve startup time even if the double segment download is unavoidable.

ghost avatar Jul 02 '18 19:07 ghost

campones commented on Jan 30, 2018, 10:19 PM UTC:

first, thanks for your (long) answer.

This is what I am using to stream or restream. Maybe you see some directives that could resolve that issue like maybe hls_sync? https://github.com/arut/nginx-rtmp-module/wiki/Directives#hls

I didn't really understand how this target duration is created. I realize that having pre.encoded with ffmpeg helps doing a smoother streaming and create a better playlist, somehow.

Also, it is normal a video stream to be heavier in term of bitrate than a cartoon. Actually this stream is web ready (it's just the one I got from their iphone app.. )

I cannot re code 30 live streams in real time, that would take a huge server just for that purpose. And remember, I m currently using a 2015-16 version of hls.js with hlsjs videojs integration from benjipot, and I don't have this issue thankfully.

The reason I m using 20s segment is basically because the token is created via php-fpm and when I got hundreds of users on a single server, if I setup a 5s segment, it will multiply the number of requests and they ll soon get a 502 bad gateway response from nginx.. Basically too many requests. Maybe my server isn't strong enough but this also is costly.

ghost avatar Jul 02 '18 19:07 ghost

Issue is still open and it still exists. I got report for user that his video is not playing and after some debugging I found that for this single file first PTS for audio is 7.289. When I execute player.currentTime(7) the video starts to play. HLS.js (or maybe browser) handles this by immediately seeking to 7th second (skipping video without audio) and playing video gracefully.

I tried to override ranges in buffered, but video.js won't play despite this, so probably fix should lay somewhere else.

misiek08 avatar Mar 18 '20 22:03 misiek08