a81238c7 by Gary Katsevman

Update HLS:

dispose tech, playlist loader
don't trigger loadedmetadata if there was an error
no need for duration update workarounds, add duration to tech
update all the tests
remove irrelevant tests
1 parent 73420aa6
......@@ -51,6 +51,7 @@
var
loader = this,
media,
mediaUpdateTimeout,
request,
haveMetadata = function(error, xhr, url) {
......@@ -88,7 +89,7 @@
// refresh live playlists after a target duration passes
if (!loader.media().endList) {
window.setTimeout(function() {
mediaUpdateTimeout = window.setTimeout(function() {
loader.trigger('mediaupdatetimeout');
}, refreshDelay);
}
......@@ -104,6 +105,13 @@
loader.state = 'HAVE_NOTHING';
loader.dispose = function() {
if (request) {
request.abort();
}
window.clearTimeout(mediaUpdateTimeout);
};
/**
* When called without any arguments, returns the currently
* active media playlist. When called with a single argument,
......@@ -213,7 +221,9 @@
haveMetadata(error,
this,
parser.manifest.playlists[0].uri);
loader.trigger('loadedmetadata');
if (!error) {
loader.trigger('loadedmetadata');
}
});
return loader.trigger('loadedplaylist');
}
......
......@@ -153,7 +153,13 @@ var
var
duration = 0,
segment,
i = (playlist.segments || []).length;
i;
if (!playlist) {
return 0;
}
i = (playlist.segments || []).length;
// if present, use the duration specified in the playlist
if (playlist.totalDuration) {
......@@ -205,16 +211,8 @@ var
* Update the player duration
*/
updateDuration = function(playlist) {
var tech;
// update the duration
player.duration(totalDuration(playlist));
// tell the flash tech of the new duration
tech = player.el().querySelector('.vjs-tech');
if(tech.vjs_setProperty) {
tech.vjs_setProperty('duration', player.duration());
}
// manually fire the duration change
player.trigger('durationchange');
};
/**
......@@ -310,7 +308,8 @@ var
}
// if no segments are available, do nothing
if (!player.hls.playlists.media().segments) {
if (player.hls.playlists.state === "HAVE_NOTHING" ||
!player.hls.playlists.media().segments) {
return;
}
......@@ -456,12 +455,12 @@ videojs.Hls = videojs.Flash.extend({
source = options.source,
settings = player.options();
player.hls = this;
delete options.source;
options.swf = settings.flash.swf;
videojs.Flash.call(this, player, options, ready);
player.hls = {};
options.source = source;
videojs.Hls.prototype.src.call(player, options.source && options.source.src);
videojs.Hls.prototype.src.call(this, options.source && options.source.src);
}
});
......@@ -472,7 +471,7 @@ videojs.Hls.prototype.src = function(src) {
source;
if (src) {
mediaSource = new videojs.MediaSource(),
mediaSource = new videojs.MediaSource();
source = {
src: videojs.URL.createObjectURL(mediaSource),
type: "video/flv"
......@@ -480,10 +479,25 @@ videojs.Hls.prototype.src = function(src) {
player.hls.mediaSource = mediaSource;
initSource(player, mediaSource, src);
this.ready(function() {
this.el().querySelector('.vjs-tech').vjs_src(source.src);
this.el().vjs_src(source.src);
});
}
}
};
videojs.Hls.prototype.duration = function() {
var playlists = this.player().hls.playlists;
if (playlists) {
return totalDuration(playlists.media());
}
return 0;
};
videojs.Hls.prototype.dispose = function() {
if (this.player().hls.playlists) {
this.player().hls.playlists.dispose();
}
videojs.Flash.prototype.dispose.call(this);
};
//for (var prop in videojs.Flash) {
//videojs.Hls[prop] = videojs.Flash[prop];
......
......@@ -15,7 +15,7 @@
<script src="../libs/qunit/qunit.js"></script>
<!-- video.js -->
<script src="../node_modules/video.js/dist/video-js/video.dev.js"></script>
<script src="../node_modules/video.js/dist/video-js/video.js"></script>
<script src="../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
<!-- HLS plugin -->
......
......@@ -22,12 +22,11 @@
var
player,
oldFlashSupported,
oldMediaSourceOpen,
oldSegmentParser,
oldSetTimeout,
oldSourceBuffer,
oldSupportsNativeHls,
xhrUrls,
oldFlashSupported,
requests,
xhr,
......@@ -82,37 +81,37 @@ var
module('HLS', {
setup: function() {
oldMediaSourceOpen = videojs.MediaSource.open;
videojs.MediaSource.open = function() {};
// mock out Flash features for phantomjs
oldFlashSupported = videojs.Flash.isSupported;
videojs.Flash.isSupported = function() {
return true;
};
oldSourceBuffer = window.videojs.SourceBuffer;
window.videojs.SourceBuffer = function() {
this.appendBuffer = function() {};
this.abort = function() {};
};
// force native HLS to be ignored
oldSupportsNativeHls = videojs.hls.supportsNativeHls;
videojs.hls.supportsNativeHls = false;
// create the test player
var video = document.createElement('video');
document.querySelector('#qunit-fixture').appendChild(video);
player = videojs(video, {
flash: {
swf: '../node_modules/video.js/dist/video-js/video-js.swf'
swf: ''//'../node_modules/video.js/dist/video-js/video-js.swf'
},
techOrder: ['flash']
techOrder: ['hls']
});
player.buffered = function() {
return videojs.createTimeRange(0, 0);
};
// store functionality that some tests need to mock
oldSegmentParser = videojs.hls.SegmentParser;
oldSegmentParser = videojs.Hls.SegmentParser;
oldSetTimeout = window.setTimeout;
// fake XHRs
......@@ -121,13 +120,18 @@ module('HLS', {
xhr.onCreate = function(xhr) {
requests.push(xhr);
};
xhrUrls = [];
var tech = player.el().querySelector('.vjs-tech');
tech.vjs_getProperty = function() {};
tech.vjs_src = function() {};
videojs.Flash.onReady(tech.id);
},
teardown: function() {
player.dispose();
videojs.Flash.isSupported = oldFlashSupported;
videojs.hls.supportsNativeHls = oldSupportsNativeHls;
videojs.hls.SegmentParser = oldSegmentParser;
videojs.MediaSource.open = oldMediaSourceOpen;
videojs.Hls.SegmentParser = oldSegmentParser;
videojs.SourceBuffer = oldSourceBuffer;
window.setTimeout = oldSetTimeout;
xhr.restore();
......@@ -140,8 +144,8 @@ test('starts playing if autoplay is specified', function() {
plays++;
};
player.options().autoplay = true;
player.hls('manifest/playlist.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/playlist.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -155,9 +159,9 @@ test('creates a PlaylistLoader on init', function() {
loadedmetadata = true;
});
player.hls('manifest/playlist.m3u8');
ok(!player.hls.playlists, 'waits for sourceopen to create the loader');
videojs.mediaSources[player.currentSrc()].trigger({
ok(!player.hls.playlists, 'waits for set src to create the loader');
player.src({src:'manifest/playlist.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
standardXHRResponse(requests[0]);
......@@ -178,8 +182,8 @@ test('sets the duration if one is available on the playlist', function() {
}
calls++;
};
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -197,8 +201,8 @@ test('calculates the duration if needed', function() {
}
durations.push(duration);
};
player.hls('http://example.com/manifest/missingExtinf.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'http://example.com/manifest/missingExtinf.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -210,11 +214,11 @@ test('calculates the duration if needed', function() {
});
test('starts downloading a segment on loadedmetadata', function() {
player.hls('manifest/media.m3u8');
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.buffered = function() {
return videojs.createTimeRange(0, 0);
};
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -228,8 +232,8 @@ test('starts downloading a segment on loadedmetadata', function() {
});
test('recognizes absolute URIs and requests them unmodified', function() {
player.hls('manifest/absoluteUris.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/absoluteUris.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -241,8 +245,8 @@ test('recognizes absolute URIs and requests them unmodified', function() {
});
test('recognizes domain-relative URLs', function() {
player.hls('manifest/domainUris.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/domainUris.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -253,14 +257,25 @@ test('recognizes domain-relative URLs', function() {
'the first segment is requested');
});
test('re-initializes the plugin for each source', function() {
var firstInit, secondInit;
player.hls('manifest/master.m3u8');
firstInit = player.hls;
player.hls('manifest/master.m3u8');
secondInit = player.hls;
test('re-initializes the tech for each source', function() {
var firstPlaylists, secondPlaylists, firstMSE, secondMSE;
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
firstPlaylists = player.hls.playlists;
firstMSE = player.hls.mediaSource;
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
secondPlaylists = player.hls.playlists;
secondMSE = player.hls.mediaSource;
notStrictEqual(firstInit, secondInit, 'the plugin object is replaced');
notStrictEqual(firstPlaylists, secondPlaylists, 'the playlist object is not reused');
notStrictEqual(firstMSE, secondMSE, 'the media source object is not reused');
});
test('triggers an error when a master playlist request errors', function() {
......@@ -268,8 +283,8 @@ test('triggers an error when a master playlist request errors', function() {
player.on('error', function() {
error = player.hls.error;
});
player.hls('manifest/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
requests.pop().respond(500);
......@@ -279,8 +294,8 @@ test('triggers an error when a master playlist request errors', function() {
});
test('downloads media playlists after loading the master', function() {
player.hls('manifest/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -309,8 +324,8 @@ test('timeupdates do not check to fill the buffer until a media playlist is read
};
this.send = function() {};
};
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
player.trigger('timeupdate');
......@@ -320,8 +335,8 @@ test('timeupdates do not check to fill the buffer until a media playlist is read
});
test('calculates the bandwidth after downloading a segment', function() {
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -337,12 +352,12 @@ test('calculates the bandwidth after downloading a segment', function() {
test('selects a playlist after segment downloads', function() {
var calls = 0;
player.hls('manifest/master.m3u8');
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.selectPlaylist = function() {
calls++;
return player.hls.playlists.master.playlists[0];
};
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -367,8 +382,8 @@ test('selects a playlist after segment downloads', function() {
test('moves to the next segment if there is a network error', function() {
var mediaIndex;
player.hls('manifest/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -386,7 +401,7 @@ test('updates the duration after switching playlists', function() {
var
calls = 0,
selectedPlaylist = false;
player.hls('manifest/master.m3u8');
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.selectPlaylist = function() {
selectedPlaylist = true;
return player.hls.playlists.master.playlists[1];
......@@ -400,7 +415,7 @@ test('updates the duration after switching playlists', function() {
calls++;
}
};
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -418,8 +433,8 @@ test('downloads additional playlists if required', function() {
playlist = {
uri: 'media3.m3u8'
};
player.hls('manifest/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -456,8 +471,8 @@ test('downloads additional playlists if required', function() {
test('selects a playlist below the current bandwidth', function() {
var playlist;
player.hls('manifest/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -478,8 +493,8 @@ test('selects a playlist below the current bandwidth', function() {
test('raises the minimum bitrate for a stream proportionially', function() {
var playlist;
player.hls('manifest/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -500,8 +515,8 @@ test('raises the minimum bitrate for a stream proportionially', function() {
test('uses the lowest bitrate if no other is suitable', function() {
var playlist;
player.hls('manifest/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -520,9 +535,9 @@ test('uses the lowest bitrate if no other is suitable', function() {
test('selects the correct rendition by player dimensions', function() {
var playlist;
player.hls('manifest/master.m3u8');
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -550,14 +565,14 @@ test('selects the correct rendition by player dimensions', function() {
test('does not download the next segment if the buffer is full', function() {
player.hls('manifest/media.m3u8');
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.currentTime = function() {
return 15;
};
player.buffered = function() {
return videojs.createTimeRange(0, 20);
};
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -569,8 +584,8 @@ test('does not download the next segment if the buffer is full', function() {
});
test('downloads the next segment if the buffer is getting low', function() {
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -597,8 +612,8 @@ test('downloads the next segment if the buffer is getting low', function() {
});
test('stops downloading segments at the end of the playlist', function() {
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
standardXHRResponse(requests[0]);
......@@ -606,13 +621,13 @@ test('stops downloading segments at the end of the playlist', function() {
player.hls.mediaIndex = 4;
player.trigger('timeupdate');
strictEqual(xhrUrls.length, 0, 'no request is made');
strictEqual(requests.length, 0, 'no request is made');
});
test('only makes one segment request at a time', function() {
var openedXhrs = 0;
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
xhr.restore();
......@@ -634,68 +649,9 @@ test('only makes one segment request at a time', function() {
xhr = sinon.useFakeXMLHttpRequest();
});
test('uses the src attribute if no options are provided and it ends in ".m3u8"', function() {
var url = 'http://example.com/services/mobile/streaming/index/master.m3u8?videoId=1824650741001';
player.el().querySelector('.vjs-tech').src = url;
player.hls();
videojs.mediaSources[player.currentSrc()].trigger({
type: 'sourceopen'
});
strictEqual(requests[0].url, url, 'currentSrc is used');
});
test('ignores src attribute if it doesn\'t have the "m3u8" extension', function() {
var tech = player.el().querySelector('.vjs-tech');
tech.src = 'basdfasdfasdfliel//.m3u9';
player.hls();
ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created');
strictEqual(requests.length, 0, 'no request is made');
tech.src = '';
player.hls();
ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created');
strictEqual(requests.length, 0, 'no request is made');
tech.src = 'http://example.com/movie.mp4?q=why.m3u8';
player.hls();
ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created');
strictEqual(requests.length, 0, 'no request is made');
tech.src = 'http://example.m3u8/movie.mp4';
player.hls();
ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created');
strictEqual(requests.length, 0, 'no request is made');
tech.src = '//example.com/movie.mp4#http://tricky.com/master.m3u8';
player.hls();
ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created');
strictEqual(requests.length, 0, 'no request is made');
});
test('activates if the first playable source is HLS', function() {
var video;
document.querySelector('#qunit-fixture').innerHTML =
'<video controls>' +
'<source type="slartibartfast$%" src="movie.slarti">' +
'<source type="application/x-mpegURL" src="movie.m3u8">' +
'<source type="video/mp4" src="movie.mp4">' +
'</video>';
video = document.querySelector('#qunit-fixture video');
player = videojs(video, {
flash: {
swf: '../node_modules/video.js/dist/video-js/video-js.swf'
},
techOrder: ['flash']
});
player.hls();
ok(player.currentSrc() in videojs.mediaSources, 'media source created');
});
test('cancels outstanding XHRs when seeking', function() {
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
standardXHRResponse(requests[0]);
......@@ -721,7 +677,7 @@ test('cancels outstanding XHRs when seeking', function() {
test('flushes the parser after each segment', function() {
var flushes = 0;
// mock out the segment parser
videojs.hls.SegmentParser = function() {
videojs.Hls.SegmentParser = function() {
this.getFlvHeader = function() {
return [];
};
......@@ -732,8 +688,8 @@ test('flushes the parser after each segment', function() {
this.tagsAvailable = function() {};
};
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -749,7 +705,7 @@ test('drops tags before the target timestamp when seeking', function() {
bytes = [];
// mock out the parser and source buffer
videojs.hls.SegmentParser = mockSegmentParser(tags);
videojs.Hls.SegmentParser = mockSegmentParser(tags);
window.videojs.SourceBuffer = function() {
this.appendBuffer = function(chunk) {
bytes.push(chunk);
......@@ -764,8 +720,8 @@ test('drops tags before the target timestamp when seeking', function() {
// push a tag into the buffer
tags.push({ pts: 0, bytes: 0 });
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
standardXHRResponse(requests[0]);
......@@ -803,7 +759,7 @@ test('clears pending buffer updates when seeking', function() {
tags = [{ pts: 0, bytes: 0 }];
// mock out the parser and source buffer
videojs.hls.SegmentParser = mockSegmentParser(tags);
videojs.Hls.SegmentParser = mockSegmentParser(tags);
window.videojs.SourceBuffer = function() {
this.appendBuffer = function(chunk) {
bytes.push(chunk);
......@@ -818,8 +774,8 @@ test('clears pending buffer updates when seeking', function() {
};
// queue up a tag to be pushed into the buffer (but don't push it yet!)
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -846,8 +802,8 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() {
player.on('error', function() {
errorTriggered = true;
});
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
requests.pop().respond(404);
......@@ -862,9 +818,9 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() {
});
test('segment 404 should trigger MEDIA_ERR_NETWORK', function () {
player.hls('manifest/media.m3u8');
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -875,9 +831,9 @@ test('segment 404 should trigger MEDIA_ERR_NETWORK', function () {
});
test('segment 500 should trigger MEDIA_ERR_ABORTED', function () {
player.hls('manifest/media.m3u8');
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -888,16 +844,16 @@ test('segment 500 should trigger MEDIA_ERR_ABORTED', function () {
});
test('has no effect if native HLS is available', function() {
videojs.hls.supportsNativeHls = true;
player.hls('http://example.com/manifest/master.m3u8');
videojs.Hls.supportsNativeHls = true;
player.src({src: 'http://example.com/manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
ok(!(player.currentSrc() in videojs.mediaSources),
'no media source was opened');
});
test('duration is Infinity for live playlists', function() {
player.hls('http://example.com/manifest/missingEndlist.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'http://example.com/manifest/missingEndlist.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -912,8 +868,8 @@ test('does not reload playlists with an endlist tag', function() {
window.setTimeout = function(callback, timeout) {
callbacks.push({ callback: callback, timeout: timeout });
};
player.hls('manifest/media.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -921,8 +877,8 @@ test('does not reload playlists with an endlist tag', function() {
});
test('updates the media index when a playlist reloads', function() {
player.hls('http://example.com/live-updating.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'http://example.com/live-updating.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -964,8 +920,8 @@ test('mediaIndex is zero before the first segment loads', function() {
this.open = function() {};
this.send = function() {};
};
player.hls('http://example.com/first-seg-load.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'http://example.com/first-seg-load.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -973,8 +929,8 @@ test('mediaIndex is zero before the first segment loads', function() {
});
test('reloads out-of-date live playlists when switching variants', function() {
player.hls('http://example.com/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'http://example.com/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -1014,8 +970,8 @@ test('does not reload master playlists', function() {
callbacks.push(callback);
};
player.hls('http://example.com/master.m3u8');
videojs.mediaSources[player.currentSrc()].trigger({
player.src({src: 'http://example.com/master.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
......@@ -1023,20 +979,33 @@ test('does not reload master playlists', function() {
});
test('if withCredentials option is used, withCredentials is set on the XHR object', function() {
player.hls({
url: 'http://example.com/media.m3u8',
withCredentials: true
});
videojs.mediaSources[player.currentSrc()].trigger({
type: 'sourceopen'
stop();
player.dispose();
var video = document.createElement('video');
document.querySelector('#qunit-fixture').appendChild(video);
player = videojs(video, {
flash: {
swf: '../node_modules/video.js/dist/video-js/video-js.swf'
},
hls: {
withCredentials: true
},
techOrder: ['hls']
}, function() {
player.src({src: 'http://example.com/media.m3u8', type: 'application/vnd.apple.mpegurl'});
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
ok(requests[0].withCredentials, "with credentials should be set to true if that option is passed in");
start();
});
ok(requests[0].withCredentials, "with credentials should be set to true if that option is passed in");
});
test('does not break if the playlist has no segments', function() {
player.hls('manifest/master.m3u8');
player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'});
try {
videojs.mediaSources[player.currentSrc()].trigger({
player.hls.mediaSource.trigger({
type: 'sourceopen'
});
requests[0].respond(200, null,
......