Is it possible to repeat the playlist without auto playing it?
Description
I have a playlist containing three videos. At the end of the last video, if the user hits the refresh button I'd like to it start at the beginning on the playlist. Right now, it just replays the last video in the playlist. Alternatively, it would be find if the first video loaded again but didn't actually play and the user had to push the play button to start the play list over again.
Steps to reproduce
Explain in detail the exact steps necessary to reproduce the issue.
window.videojs('my-video', function () {
this.playlist([
{
sources: [{
src: 'http://server.com/video1.mp4',
type: 'video/mp4'
}],
poster: 'http://server.com/thumb1.png'
},
{
sources: [{
src: 'http://server.com/video2.mp4',
type: 'video/mp4'
}],
poster: 'http://server.com/thumb2.png'
},
{
sources: [{
src: 'http://server.com/video3.mp4',
type: 'video/mp4'
}],
poster: 'http://server.com/thumb3.png'
}
]);
this.playlist.autoadvance(0);
});
I also tried adding this:
this.playlist.repeat(true);
this.on('playlistitem', function(event, data) {
if (data.playlistItemId_ === 1) {
self.vjsVideo.pause();
}
});
but to no avail.
Results
Expected
I would like for the entire playlist to start over from the beginning when the user clicks the refresh button after the last video is done. Alternatively, it would be find if the first video loaded again but didn't actually play.
Actual
The last video in the playlist plays again.
versions
videojs
7.7.5
browsers
Probably all of them but tested on Mac Chrome, Mac Safari, Mac Firefox
OSes
Probably all but tested on macOS 10.14.5 (Mojave)
With repeat(true), it would at the end of the playlist. It doesn't need to be used in conjunction with autoadvance, which seems you do not want. Or do you want autoadvance to not advance at the end of the playlist until the user restarts?
I guess ideally what I'd like is for it to auto advance through all three videos and then stop. If the user hits refresh it starts again at the first video and auto advances through them all again.
If that's not possible, then it could auto advance through all three videos and go back to the first, but not start playing it until the user hits the play button.
With repeat(true), I guess I would set autoadvance when then on a playlistitem event, check whether playlist.currentIndex() === playlist.lastIndex() and then turn off autoadvance. Then turn on autoadvance again when the user clicks play again.
when the user clicks play again
It should only happen when he clicks "replay" actually, but that does not have an own event?
Anyway, I got it working with this, which looks ugly as heck:
this.player.playlist.autoadvance(0);
this.player.on('playlistitem', () => {
const playlist = this.player.playlist;
if (playlist.currentIndex() === playlist.lastIndex()) {
playlist.autoadvance(); // autoadvance off on last item
this.player.one('ended', () => { // after playback ended (playlist finished)
this.player.one('play', () => { // after new play start (replay)
playlist.currentItem(0); // without this, the last item would be played again and then the playlist restarted
playlist.autoadvance(0);
});
});
}
});
Or do you want autoadvance to not advance at the end of the playlist until the user restarts?
Yes please. It's a pretty straightforward use-case I think. I want to advance the list, not loop. For that, there is an own player option. Once finished playback should stop and the playlist should start from the beginning if "replay" is pressed. So if player.loop() === true, current behaviour is okay even (with repeat = true).
With player.playlist.repeat(true) you shouldn't need the playlist.currentItem(0).
I think the issue is that autoadvance and repeat currently are independent. Autoadvance kicks in when a playlist item ends until we are out of playlist items. Repeat kicks in when the playlist ends and restarts the playlist. Thus, autoadvance kicks in again and will loop indefinitely.
We potentially want another option, perhaps as part of repeat, that handles this use-case in the plugin rather than requiring you to do it yourself. Such that autoadvance advances to the end of the playlist and stops and then repeat kicks in so that the next item in the playlist is the first item again.
If you have thoughts about how such an option would look like considering the current API, I'd be happy to take a look, it may be a while before I have the time to look into it myself.
With player.playlist.repeat(true) you shouldn't need the playlist.currentItem(0).
I thought so too, but it is needed, because else the last item will be played once again before advancing to the first. I guess that's because the "next item" is only set on ended and this is skipped if autoadvance is off. So in the moment you press "play", the current item is still the last playlist item. I tried to set currentItem on ended, but that will just automatically start playing again, so it behaves like loop, which is not what I want.
If you have thoughts about how such an option would look like considering the current API
I'd be in favor of making use of the existing loop() flag of the player, which is meant exactly for that purpose, instead of introducing a new flag only for the playlist. Of course, that would slightly change behaviour and hence would be considered a breaking change. But it's the cleanest approach to solve this IMO.
So:
- autoadvance + repeat + loop = current behaviour of looping the whole playlist indefinintely
- autoadvance + repeat - loop = run whole playlist once and restart from first item on "replay"
- autoadvance - repeat + loop = run whole playlist once and loop last item indefinitely
- autoadvance - repeat - loop = run whole playlist once then replay last item on "replay"
autoadvance + repeat + loop is just repeating the first video