diff --git a/README.md b/README.md index 4729679d4..82739e578 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ videojs(video, {html5: { // or var options = {hls: { - withCredentials: true; + withCredentials: true }}; videojs(video, {html5: options}); @@ -581,6 +581,10 @@ will have this structure ```javascript cue.value = { + byteLength, // The size of the segment in bytes + bandwidth, // The peak bitrate reported by the segment's playlist + resolution, // The resolution reported by the segment's playlist + codecs, // The codecs reported by the segment's playlist uri, // The Segment uri timeline, // Timeline of the segment for detecting discontinuities playlist, // The Playlist uri diff --git a/src/master-playlist-controller.js b/src/master-playlist-controller.js index 9f16beb37..4545a597c 100644 --- a/src/master-playlist-controller.js +++ b/src/master-playlist-controller.js @@ -604,7 +604,13 @@ export class MasterPlaylistController extends videojs.EventTarget { // code in video.js but is required because play() must be invoked // *after* the media source has opened. if (this.tech_.autoplay()) { - this.tech_.play(); + const playPromise = this.tech_.play(); + + // Catch/silence error when a pause interrupts a play request + // on browsers which return a promise + if (typeof playPromise !== 'undefined' && typeof playPromise.then === 'function') { + playPromise.then(null, (e) => {}); + } } this.trigger('sourceopen'); diff --git a/src/segment-loader.js b/src/segment-loader.js index 8ef7ba51d..92615b69e 100644 --- a/src/segment-loader.js +++ b/src/segment-loader.js @@ -1330,6 +1330,10 @@ export default class SegmentLoader extends videojs.EventTarget { const Cue = window.WebKitDataCue || window.VTTCue; const value = { + bandwidth: segmentInfo.playlist.attributes.BANDWIDTH, + resolution: segmentInfo.playlist.attributes.RESOLUTION, + codecs: segmentInfo.playlist.attributes.CODECS, + byteLength: segmentInfo.byteLength, uri: segmentInfo.uri, timeline: segmentInfo.timeline, playlist: segmentInfo.playlist.uri, diff --git a/test/master-playlist-controller.test.js b/test/master-playlist-controller.test.js index 6da48882b..ab2ec1462 100644 --- a/test/master-playlist-controller.test.js +++ b/test/master-playlist-controller.test.js @@ -2501,3 +2501,18 @@ QUnit.test('properly configures loader mime types', function(assert) { 'correct mime type for audio segment loader'); assert.notOk(audioMimeTypeCalls[0][1], 'no source buffer emitter'); }); + +QUnit.test('Exception in play promise should be caught', function(assert) { + const mpc = this.masterPlaylistController; + + mpc.setupSourceBuffers = () => true; + mpc.tech_ = { + autoplay: () => true, + play: () => new Promise(function(resolve, reject) { + reject(new DOMException()); + }) + }; + mpc.handleSourceOpen_(); + + assert.ok(true, 'rejects dom exception'); +}); diff --git a/test/segment-loader.test.js b/test/segment-loader.test.js index e74209487..e10ffa392 100644 --- a/test/segment-loader.test.js +++ b/test/segment-loader.test.js @@ -413,7 +413,12 @@ QUnit.module('SegmentLoader', function(hooks) { 'as they are buffered', function(assert) { const track = loader.segmentMetadataTrack_; - let playlist = playlistWithDuration(50); + const attributes = { + BANDWIDTH: 3500000, + RESOLUTION: '1920x1080', + CODECS: 'mp4a.40.5,avc1.42001e' + }; + let playlist = playlistWithDuration(50, {attributes}); let probeResponse; let expectedCue; @@ -441,7 +446,11 @@ QUnit.module('SegmentLoader', function(hooks) { timeline: 0, playlist: 'playlist.m3u8', start: 0, - end: 9.5 + end: 9.5, + bandwidth: 3500000, + resolution: '1920x1080', + codecs: 'mp4a.40.5,avc1.42001e', + byteLength: 10 }; assert.equal(track.cues.length, 1, 'one cue added for segment'); @@ -458,7 +467,11 @@ QUnit.module('SegmentLoader', function(hooks) { timeline: 0, playlist: 'playlist.m3u8', start: 9.56, - end: 19.2 + end: 19.2, + bandwidth: 3500000, + resolution: '1920x1080', + codecs: 'mp4a.40.5,avc1.42001e', + byteLength: 10 }; assert.equal(track.cues.length, 2, 'one cue added for segment'); @@ -475,7 +488,11 @@ QUnit.module('SegmentLoader', function(hooks) { timeline: 0, playlist: 'playlist.m3u8', start: 19.24, - end: 28.99 + end: 28.99, + bandwidth: 3500000, + resolution: '1920x1080', + codecs: 'mp4a.40.5,avc1.42001e', + byteLength: 10 }; assert.equal(track.cues.length, 3, 'one cue added for segment'); @@ -494,7 +511,11 @@ QUnit.module('SegmentLoader', function(hooks) { timeline: 0, playlist: 'playlist.m3u8', start: 19.21, - end: 28.98 + end: 28.98, + bandwidth: 3500000, + resolution: '1920x1080', + codecs: 'mp4a.40.5,avc1.42001e', + byteLength: 10 }; assert.equal(track.cues.length, 3, 'overlapped cue removed, new one added'); diff --git a/test/test-helpers.js b/test/test-helpers.js index c8eac09d5..519e9c89e 100644 --- a/test/test-helpers.js +++ b/test/test-helpers.js @@ -374,7 +374,7 @@ export const playlistWithDuration = function(time, conf) { uri: conf && typeof conf.uri !== 'undefined' ? conf.uri : 'playlist.m3u8', discontinuitySequence: conf && conf.discontinuitySequence ? conf.discontinuitySequence : 0, - attributes: {} + attributes: conf && typeof conf.attributes !== 'undefined' ? conf.attributes : {} }; let count = Math.floor(time / 10); let remainder = time % 10;