c5bec582 by David LaPalomento

Treat invalid keys as key failures

If the key is not the correct size, retry the request once. If the retry still fails, try moving on to find a playable segment.
1 parent 27e42bfb
...@@ -557,13 +557,13 @@ videojs.Hls.prototype.fetchKeys = function(playlist, index) { ...@@ -557,13 +557,13 @@ videojs.Hls.prototype.fetchKeys = function(playlist, index) {
557 key = playlist.segments[i].key; 557 key = playlist.segments[i].key;
558 if (key && !key.bytes && !keyFailed(key)) { 558 if (key && !key.bytes && !keyFailed(key)) {
559 keyXhr = videojs.Hls.xhr({ 559 keyXhr = videojs.Hls.xhr({
560 url: key.uri, 560 url: resolveUrl(playlist.uri, key.uri),
561 responseType: 'arraybuffer', 561 responseType: 'arraybuffer',
562 withCredentials: settings.withCredentials 562 withCredentials: settings.withCredentials
563 }, function(err, url) { 563 }, function(err, url) {
564 keyXhr = null; 564 keyXhr = null;
565 565
566 if (err) { 566 if (err || !this.response || this.response.byteLength !== 16) {
567 key.retries = key.retries || 0; 567 key.retries = key.retries || 0;
568 key.retries++; 568 key.retries++;
569 if (!this.aborted) { 569 if (!this.aborted) {
......
...@@ -1664,4 +1664,68 @@ test('switching playlists with an outstanding key request does not stall playbac ...@@ -1664,4 +1664,68 @@ test('switching playlists with an outstanding key request does not stall playbac
1664 'requested the segment and key'); 1664 'requested the segment and key');
1665 }); 1665 });
1666 1666
1667 test('resovles relative key URLs against the playlist', function() {
1668 player.src({
1669 src: 'https://example.com/media.m3u8',
1670 type: 'application/vnd.apple.mpegurl'
1671 });
1672 openMediaSource(player);
1673
1674 requests.shift().respond(200, null,
1675 '#EXTM3U\n' +
1676 '#EXT-X-MEDIA-SEQUENCE:5\n' +
1677 '#EXT-X-KEY:METHOD=AES-128,URI="key.php?r=52"\n' +
1678 '#EXTINF:2.833,\n' +
1679 'http://media.example.com/fileSequence52-A.ts\n');
1680 equal(requests[0].url, 'https://example.com/key.php?r=52', 'resolves the key URL');
1681 });
1682
1683 test('treats invalid keys as a key request failure', function() {
1684 var tags = [{ pts: 0, bytes: 0 }], bytes = [];
1685 videojs.Hls.SegmentParser = mockSegmentParser(tags);
1686 window.videojs.SourceBuffer = function() {
1687 this.appendBuffer = function(chunk) {
1688 bytes.push(chunk);
1689 };
1690 };
1691 player.src({
1692 src: 'https://example.com/media.m3u8',
1693 type: 'application/vnd.apple.mpegurl'
1694 });
1695 openMediaSource(player);
1696 requests.shift().respond(200, null,
1697 '#EXTM3U\n' +
1698 '#EXT-X-MEDIA-SEQUENCE:5\n' +
1699 '#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52"\n' +
1700 '#EXTINF:2.833,\n' +
1701 'http://media.example.com/fileSequence52-A.ts\n' +
1702 '#EXT-X-KEY:METHOD=NONE\n' +
1703 '#EXTINF:15.0,\n' +
1704 'http://media.example.com/fileSequence52-B.ts\n');
1705 // keys should be 16 bytes long
1706 requests[0].response = new Uint8Array(1).buffer;
1707 requests.shift().respond(200, null, '');
1708 // segment request
1709 standardXHRResponse(requests.shift());
1710
1711 equal(requests[0].url, 'https://priv.example.com/key.php?r=52', 'retries the key');
1712
1713 // the retried response is invalid, too
1714 requests[0].response = new Uint8Array(1);
1715 requests.shift().respond(200, null, '');
1716
1717 // the first segment should be dropped and playback moves on
1718 player.trigger('timeupdate');
1719 equal(bytes.length, 1, 'did not append bytes');
1720 equal(bytes[0], 'flv', 'appended the flv header');
1721
1722 tags.length = 0;
1723 tags.push({ pts: 1, bytes: 1 });
1724 // second segment request
1725 standardXHRResponse(requests.shift());
1726
1727 equal(bytes.length, 2, 'appended bytes');
1728 equal(1, bytes[1], 'skipped to the second segment');
1729 });
1730
1667 })(window, window.videojs); 1731 })(window, window.videojs);
......