videojs / videojs-contrib-hls

HLS library for video.js
http://videojs.github.io/videojs-contrib-hls/
Other
2.84k stars 793 forks source link

DVR Functionality possible? #354

Closed chriswiggins closed 6 years ago

chriswiggins commented 9 years ago

I'm trying to use HLS with a sliding window of 60 minutes however all I get when using this playback tech is 'live' on the control bar.

I've tried the following but the live bar stays there:

videojs('videojs', {
    controlBar: {
        muteToggle: false,
        volumeControl: false
    }
}, function(){
    player = this;
    this.removeClass('vjs-live');

    this.on('timeupdate', function(){
        if(player.duration() < player.currentTime() || !isFinite(player.duration()) ){
            player.duration( player.currentTime() );
        }
    });
});

With FlasHLS for example, the duration is the playlist length and currentTime is where the player is in that duration (normally 3 segments behind the latest). Is there a way we can do the same with this? Happy to submit a PR if someone can point me in the right direction!

Thanks Chris

dmlap commented 9 years ago

We're shooting to match iOS's API behavior during live streams so that it's possible to build a cross-platform live DVR set of controls. Apple's implementation (and the HTML spec too from my reading) make duration Infinity for live streams and use the seekable property to expose the sliding content window. Current time is zeroed at the earliest available media timeline position when the user began loading the stream.

contrib-hls has had a spec-compliant seekable implementation since 0.17 so it should be possible to build live DVR controls now. A PR for this project that added live DVR controls would be awesome if you're up for it. If you're able to build it so it works on iOS too, we've been wanting something like this for the main video.js repo for awhile. If you have any questions, feel free to drop them in this thread-- I'd be happy to help!

chriswiggins commented 9 years ago

Lots of questions about where to start but I'll have a look around and let you know :-)

Guessing I'll just start looking at what parses the m3u8 and sets the duration. Hopefully it'll be fairly straightforward to know what segment we're currently displaying vs what segment is at the end of the playlist. Does video.js provide a mechanism to "go back to live" or should we just rely on the user seeking to the end? I suppose I could always add a controlbar plugin to add that feature.

I'm not sure if this will work on iOS as I've never had any success with the native player (it just shows live). Does video.js just talk with the player or does it set a whole lot of things itself?

Thanks for the support @dmlap !

chriswiggins commented 9 years ago

I'm giving this a go again but have run into an issue. I need to access properties set inside the HLS tech from another plugin however player.hls seems to be undefined? It is mentioned in the readme that there are methods available there so i'm wondering why I can't access them both inside another plugin or directly after setting up the player:

var player = videojs('video');
    player.play();
    player.on('timeupdate', function(duration){
        console.log(player.hls); //<------ This is undefined?
    });

Help appreciated as I'm thinking this will be easier than first anticipated :-)

chriswiggins commented 9 years ago

Scratch that - it just doesn't show up in Safari. Although that in itself raises another potential problem for another day!

dmlap commented 9 years ago

@chriswiggins player.hls only shows up when this project is being used and we don't polyfill HLS anywhere it's supported natively (e.g. Safari). You should still be able to build live DVR controls without accessing the extended properties supported by this tech, though. Check out the seekable attribute for a cross-browser way of getting information on the currently available playback positions in a live stream. It should behave the same way whether contrib-hls is being used to provide HLS support or it's built natively into the video element.

chriswiggins commented 9 years ago

Back to playing with this again - seems to be a weekend sort of project :-)

Its weird I now can't get my development environment to work at all now, nor using any public live HLS playlists. I'll try and sort this out but its been an hour and still no luck. It works in Safari but something weird must be going on with my Flash install as it doesn't work in Chrome/Firefox...

However I do still have a question or two. Its appears as if player.seekable().end(0) gives the current position in the live playlist, not the end? I.e the 'end' of the playlist should typically be about 3 seconds ahead of the current position due to HLS having to buffer at least 3 segments correct? Is there a way to figure this out?

Also, how can I modify the behaviour of the controlbar to enable scrubbing? Can I override events emitted by the HLS plugin to trick the controlbar into allowing scrubbing etc?

Appreciate the help @dmlap - hoping to put more time into this in the coming weeks too

kmahelona commented 9 years ago

Hey, we're a non-profit media company in NZ (http://tehiku.nz) and we're looking for a good, open-source, nDVR player for our livestreams. Had a play with clappr, which is great, but buggy (and currently not building).

If you ever need a live nDVR stream let me know and I'll spin up some servers and make a stream for you. I only ask for a time window so we're not incuring too much AWS costs. Also keen to help with testing.

nickygerritsen commented 8 years ago

Hmmm I came across this issue and I think it is the best place for the following:

Before even starting to try to implement some UI for DVR, it seems there is some bug: the player.seekable does not get updated during playback of the stream.

I.e. it has one range in the beginning and that range is static; it is never updated to a new range. Is this a bug or is this never implemented?

nickygerritsen commented 8 years ago

Ah it seems this is expected, as this timerange is relative to the first moment that is still playable. E.g. for me it is always [0,120] as I have a DVR length of 120.

However, how do I convert this into something I can pass to currentTime, i.e. how do I know what timing we can use? Preferably without using any HLS plugin specifics, as then a DVR could be created for any stream that is live and seekable, i.e. also for DASH and native-HLS.

nickygerritsen commented 8 years ago

Hmmm now I'm really confused; it does seem to update the data correctly using values I can pass to setCurrentTime.

However it only updates every few seconds, so if we were going to use this for DVR and the user seeks to the beginning of the DVR window, that part will most probably be gone already. Any suggestions on this?

FDiskas commented 8 years ago

Same problems :+1:

FDiskas commented 8 years ago

I'm actualy parsing the playlist - searching for the ENDLIST tag then forsing with player.playlists.media().endList = true; :) hack as hell :dancers:

FDiskas commented 8 years ago

Result https://youtu.be/7wltaNrqqtQ My problem, is that videojs is not triggering ended event then on DVR updatets metatag endlist

jaq316 commented 8 years ago

@FDiskas... The video at the link seems to be removed. Has anyone had any luck implementing this?

Jrubensson commented 8 years ago

Just looked into this, since we switched from JW Player to VideoJS but are missing the DVR. Did anyone solve this?

AlexMurm commented 8 years ago

I also have the same issue. Link to reproduce: http://origin.platformcraft.ru/alexmurm/videojs/5tv_5.html

Jrubensson commented 7 years ago

This plugin solved our issue: https://github.com/toolbox-tve/videojs-dvrseekbar

forbesjo commented 6 years ago

Closing due to inactivity, going to open an enhancement issue in VHS to allow built-in DVR