Skip to content

Commit

Permalink
feat: expose custom M3U8 parser API (#331)
Browse files Browse the repository at this point in the history
  • Loading branch information
forbesjo committed Jan 4, 2019
1 parent c14d415 commit b0643a4
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ Video.js Compatibility: 6.0, 7.0
- [enableLowInitialPlaylist](#enablelowinitialplaylist)
- [limitRenditionByPlayerDimensions](#limitrenditionbyplayerdimensions)
- [smoothQualityChange](#smoothqualitychange)
- [allowSeeksWithinUnsafeLiveWindow](#allowSeeksWithinUnsafeLiveWindow)
- [allowSeeksWithinUnsafeLiveWindow](#allowseekswithinunsafelivewindow)
- [customTagParsers](#customtagparsers)
- [Runtime Properties](#runtime-properties)
- [hls.playlists.master](#hlsplaylistsmaster)
- [hls.playlists.media](#hlsplaylistsmedia)
Expand Down Expand Up @@ -394,6 +395,12 @@ content.

The property defaults to `false`.

##### customTagParsers
* Type: `Array`
* can be used as a source option

With `customTagParsers` you can pass an array of custom m3u8 tag parser objects. See https://github.com/videojs/m3u8-parser#custom-parsers

### Runtime Properties
Runtime properties are attached to the tech object when HLS is in
use. You can get a reference to the HLS source handler like this:
Expand Down
10 changes: 10 additions & 0 deletions src/playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ export default class PlaylistLoader extends EventTarget {
this.hls_ = hls;
this.withCredentials = withCredentials;

const options = hls.options_;

this.customTagParsers = (options && options.customTagParsers) || [];

if (!this.srcUrl) {
throw new Error('A non-empty playlist URL is required');
}
Expand Down Expand Up @@ -266,6 +270,9 @@ export default class PlaylistLoader extends EventTarget {

const parser = new M3u8Parser();

// adding custom tag parsers
this.customTagParsers.forEach(customParser => parser.addParser(customParser));

parser.push(xhr.responseText);
parser.end();
parser.manifest.uri = url;
Expand Down Expand Up @@ -505,6 +512,9 @@ export default class PlaylistLoader extends EventTarget {

const parser = new M3u8Parser();

// adding custom tag parsers
this.customTagParsers.forEach(customParser => parser.addParser(customParser));

parser.push(req.responseText);
parser.end();

Expand Down
9 changes: 8 additions & 1 deletion src/videojs-http-streaming.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ class HlsHandler extends Component {
typeof this.source_.useBandwidthFromLocalStorage !== 'undefined' ?
this.source_.useBandwidthFromLocalStorage :
this.options_.useBandwidthFromLocalStorage || false;
this.options_.customTagParsers = this.options_.customTagParsers || [];

if (typeof this.options_.blacklistDuration !== 'number') {
this.options_.blacklistDuration = 5 * 60;
Expand Down Expand Up @@ -433,7 +434,13 @@ class HlsHandler extends Component {
this.options_.bandwidth === Config.INITIAL_BANDWIDTH;

// grab options passed to player.src
['withCredentials', 'limitRenditionByPlayerDimensions', 'bandwidth', 'smoothQualityChange'].forEach((option) => {
[
'withCredentials',
'limitRenditionByPlayerDimensions',
'bandwidth',
'smoothQualityChange',
'customTagParsers'
].forEach((option) => {
if (typeof this.source_[option] !== 'undefined') {
this.options_[option] = this.source_[option];
}
Expand Down
26 changes: 26 additions & 0 deletions test/playlist-loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,32 @@ QUnit.test('logs warning for master playlist with invalid STREAM-INF', function(
'logged a warning');
});

QUnit.test('executes custom tag parsers', function(assert) {
const customTagParsers = [{
expression: /#PARSER/,
customType: 'test',
segment: true
}];

this.fakeHls.options_ = { customTagParsers };

let loader = new PlaylistLoader('master.m3u8', this.fakeHls);

loader.load();
this.requests.pop().respond(200, null,
'#EXTM3U\n' +
'#PARSER:parsed\n' +
'#EXTINF:10,\n' +
'0.ts\n' +
'#EXT-X-ENDLIST\n');

const segment = loader.master.playlists[0].segments[0];

assert.strictEqual(segment.custom.test, '#PARSER:parsed', 'parsed custom tag');

delete this.fakeHls.options_;
});

QUnit.test('jumps to HAVE_METADATA when initialized with a media playlist',
function(assert) {
let loadedmetadatas = 0;
Expand Down

0 comments on commit b0643a4

Please sign in to comment.