VID-5: M3U Support



Issue Information

Issue Type: New Feature
 
Priority: Major
Status: Closed

Reported By:
Ben Tasker
Assigned To:
Ben Tasker
Project: Videos.bentasker.co.uk (VID)
Resolution: Done (2019-12-15 13:35:04)
Target version: v0.15,

Created: 2019-03-27 16:35:08
Time Spent Working


Description
Surprising as it may be, VideoJS does not natively support M3U format playlists.

I hacked together a translator yesterday whilst fooling around with something else, so it'd be good to take that work and translate it into something which can be used here.

Essentially, what's needed is to fetch the M3U and iterate over its items in order to build a JSON object which can then be passed into the videojs-playlist plugin (may also want to consider adding support for videojs-playlist-ui at the same time).


Issue Links

Toggle State Changes

Activity


btasker added 'VNEXT' to Fix Version
btasker removed 'v0.13' from Fix Version
btasker added 'VNEXT' to Fix Version
btasker removed 'v0.14' from Fix Version
One thing to note about the implementation referred to in the description, it was set up so that it could play indefinitely - refetching the playlist and appending the contents periodically. This eventually leads to browser tab lockups as we consume an ever increasing amount of memory.
The method used in that original hacked together implementation is fairly simple. It places a XMLHttpRequest for the M3U, using an onload JS event to call function parseM3U once the playlist has been fetched.
function parseM3U(){
    window.videoList = []
    lines = this.responseText.split('\n');
    domain = window.location.hostname;
    var o;
    for (var i=0; i<lines.length; i++){

        if (lines[i][0] == "/" && lines[i] != "/shuffle.m3u"){
          o = {
                sources : [
                    {
                        src: 'https://'+domain+lines[i],
                        type: 'video/mp4'
                    }
                ]
            }
          window.videoList.push(o);
        }
    }
    window.player.playlist(window.videoList);
    window.player.playlist.autoadvance(0); // play all
    window.player.playlist.first();
    window.player.play();
}

As we can see, this happens after the player has been instantiated, so for each video it's just a case of pushing the URL into the player's playlist. The function does assume that the video will be of type video/mp4, so that'd need changing (though we can probably just use guessMimeFromUrl as implemented in VID-14
Repo: videos.bentasker.co.uk
Host:Rimmer

commit a524593699e3a2dca40b947d0270eda51d8a8f3e
Author: B Tasker <github@<Domain Hidden>>
Date: Sun Dec 15 12:22:21 2019 +0000

Commit Message: VID-5 Add M3U playlist support

This is an initial and quite basic implementation, so has a number of caveats

* Support for playlist-ui hasn't been added yet, so no playlist related controls (including next/previous) are exposed
* If tokenisation is enabled server side, playback will fail - we only currently mint a token for the M3U itself
* External (i.e. non videos.bentasker.co.uk) files can be played from the playlist (this is probably a good thing)
* If the video items path starts with "/" the current domain name (i.e. window.location.hostname) will be prepended. This will be wrong in the majority of situations but acts as a placeholder

Also adds a M3U which was used for testing

resources/embed/embed.js | 98 +++++++++++++++++++++++++++++++++++++--
resources/tests/vid5-test2.m3u | 6 +++
2 files changed, 99 insertions(+), 5 deletions(-)


View Commit | View Changes
Repo: videos.bentasker.co.uk
Host:Rimmer

commit 87afdbe3737a4f60fc7a2204f0463ee5e672d321
Author: B Tasker <github@<Domain Hidden>>
Date: Sun Dec 15 12:54:35 2019 +0000

Commit Message: VID-5 Add playlist-ui but don't trigger it

The plugin relies on quite a lot of information that isn't available when our source is an M3U file:

* Name
* Thumbnail
* Duration

So what we get is a grey box the width of the player with nothing obvious in it.

Have left the hooks in, commented out as they may well prove useful if we want to support some form of Javascript playlist in future

resources/embed/embed.js | 30 +-
resources/js/playlist-ui/lang/de.js | 5 +
resources/js/playlist-ui/lang/en.js | 5 +
resources/js/playlist-ui/lang/es.js | 5 +
resources/js/playlist-ui/lang/fr.js | 5 +
resources/js/playlist-ui/lang/ja.js | 5 +
resources/js/playlist-ui/lang/ko.js | 5 +
resources/js/playlist-ui/lang/zh-Hans.js | 5 +
resources/js/playlist-ui/lang/zh-Hant.js | 5 +
resources/js/playlist-ui/package/CHANGELOG.md | 183 +
resources/js/playlist-ui/package/CONTRIBUTING.md | 30 +
resources/js/playlist-ui/package/LICENSE | 13 +
resources/js/playlist-ui/package/README.md | 110 +
resources/js/playlist-ui/package/dist/lang/de.js | 5 +
resources/js/playlist-ui/package/dist/lang/en.js | 5 +
resources/js/playlist-ui/package/dist/lang/es.js | 5 +
resources/js/playlist-ui/package/dist/lang/fr.js | 5 +
resources/js/playlist-ui/package/dist/lang/ja.js | 5 +
resources/js/playlist-ui/package/dist/lang/ko.js | 5 +
.../js/playlist-ui/package/dist/lang/zh-Hans.js | 5 +
.../js/playlist-ui/package/dist/lang/zh-Hant.js | 5 +
.../package/dist/videojs-playlist-ui.cjs.js | 504 ++
.../package/dist/videojs-playlist-ui.css | 1 +
.../package/dist/videojs-playlist-ui.es.js | 500 ++
.../package/dist/videojs-playlist-ui.js | 508 ++
.../package/dist/videojs-playlist-ui.min.js | 2 +
.../package/dist/videojs-playlist-ui.vertical.css | 1 +
.../videojs-playlist-ui.vertical.no-prefix.css | 1 +
resources/js/playlist-ui/package/index.html | 18 +
resources/js/playlist-ui/package/package.json | 112 +
.../js/playlist-ui/package/scripts/karma.conf.js | 13 +
.../playlist-ui/package/scripts/postcss.config.js | 9 +
.../playlist-ui/package/scripts/rollup.config.js | 11 +
resources/js/playlist-ui/package/src/plugin.js | 479 ++
resources/js/playlist-ui/package/src/plugin.scss | 288 +
.../js/playlist-ui/package/test/dist/bundle.js | 6307 ++++++++++++++++++++
.../package/test/example/oceans-low.jpg | Bin 0 -> 30787 bytes
.../js/playlist-ui/package/test/example/oceans.jpg | Bin 0 -> 87243 bytes
.../js/playlist-ui/package/test/plugin.test.js | 618 ++
.../js/playlist-ui/videojs-playlist-ui-3.6.0.tgz | Bin 0 -> 163164 bytes
.../js/playlist-ui/videojs-playlist-ui.cjs.js | 504 ++
resources/js/playlist-ui/videojs-playlist-ui.css | 1 +
resources/js/playlist-ui/videojs-playlist-ui.es.js | 500 ++
resources/js/playlist-ui/videojs-playlist-ui.js | 508 ++
.../js/playlist-ui/videojs-playlist-ui.min.js | 2 +
.../playlist-ui/videojs-playlist-ui.vertical.css | 1 +
.../videojs-playlist-ui.vertical.no-prefix.css | 1 +
47 files changed, 11334 insertions(+), 1 deletions(-)


View Commit | View Changes
I started embedding playlist-ui but testing showed it isn't really suitable for this (at least not without quite a lot of work).

As we can see in their example call, it uses sources information that we just don't have available when using a M3U as the original source:
player.playlist([{
      name: 'Disney\'s Oceans 1',
      description: 'Explore the depths of our planet\'s oceans. ' +
        'Experience the stories that connect their world to ours. ' +
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' +
        'sed do eiusmod tempor incididunt ut labore et dolore magna ' +
        'aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco ' +
        'laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure ' +
        'dolor in reprehenderit in voluptate velit esse cillum dolore eu ' +
        'fugiat nulla pariatur. Excepteur sint occaecat cupidatat non ' +
        'proident, sunt in culpa qui officia deserunt mollit anim id est ' +
        'laborum.',
      duration: 45,
      sources: [
        { src: 'http://vjs.zencdn.net/v/oceans.mp4', type: 'video/mp4' },
        { src: 'http://vjs.zencdn.net/v/oceans.webm', type: 'video/webm' },
      ],
      // you can use <picture> syntax to display responsive images
      thumbnail: [
        {
          srcset: 'test/example/oceans.jpg',
          type: 'image/jpeg',
          media: '(min-width: 400px;)'
        },
        {
          src: 'test/example/oceans-low.jpg'
        }
      ]
    },

What we have available is literally just the URL to the media file.

The result is that the plugin generates a div with a grey background, there's nothing really visible there at all.

The reason I've left the hooks in place is I'm not averse to building a "special" playlist format (maybe JSON?) which does contain this information. The plugin will probably be quite useful for that. In the meantime the limited things it does pull in for an M3U have no negative impact.

To finish off this issue then, probably need to look at adding a couple of buttons to the player - Next/Previous - so that it's possible to navigate through the playlist
Commit 0aace65 adds Next and Previous buttons to the control bar when a M3U has been supplied.

I'm going to mark this FR as done - given the issues with playlist-ui I think it's better handled/reintroduced under a new FR for a custom playlist format
btasker changed status from 'Open' to 'Resolved'
btasker added 'Done' to resolution
btasker changed status from 'Resolved' to 'Closed'
Repo: videos.bentasker.co.uk
Host:Rimmer

commit 0aace65f256556d24823b7dccb3f75af33f25bfa
Author: B Tasker <github@<Domain Hidden>>
Date: Sun Dec 15 13:33:20 2019 +0000

Commit Message: VID-5 Add playlist nav buttons - Prev/Next to control bar

resources/embed/embed.js | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)


View Commit | View Changes