Merge pull request #508 from videojs/rendition-selection
Rendition selection
Showing
3 changed files
with
46 additions
and
18 deletions
... | @@ -632,7 +632,6 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { | ... | @@ -632,7 +632,6 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { |
632 | now = +new Date(), | 632 | now = +new Date(), |
633 | i, | 633 | i, |
634 | variant, | 634 | variant, |
635 | oldvariant, | ||
636 | bandwidthBestVariant, | 635 | bandwidthBestVariant, |
637 | resolutionPlusOne, | 636 | resolutionPlusOne, |
638 | resolutionBestVariant, | 637 | resolutionBestVariant, |
... | @@ -689,7 +688,6 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { | ... | @@ -689,7 +688,6 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { |
689 | // iterate through the bandwidth-filtered playlists and find | 688 | // iterate through the bandwidth-filtered playlists and find |
690 | // best rendition by player dimension | 689 | // best rendition by player dimension |
691 | while (i--) { | 690 | while (i--) { |
692 | oldvariant = variant; | ||
693 | variant = bandwidthPlaylists[i]; | 691 | variant = bandwidthPlaylists[i]; |
694 | 692 | ||
695 | // ignore playlists without resolution information | 693 | // ignore playlists without resolution information |
... | @@ -700,9 +698,9 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { | ... | @@ -700,9 +698,9 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { |
700 | continue; | 698 | continue; |
701 | } | 699 | } |
702 | 700 | ||
703 | |||
704 | // since the playlists are sorted, the first variant that has | 701 | // since the playlists are sorted, the first variant that has |
705 | // dimensions less than or equal to the player size is the best | 702 | // dimensions less than or equal to the player size is the best |
703 | |||
706 | if (variant.attributes.RESOLUTION.width === width && | 704 | if (variant.attributes.RESOLUTION.width === width && |
707 | variant.attributes.RESOLUTION.height === height) { | 705 | variant.attributes.RESOLUTION.height === height) { |
708 | // if we have the exact resolution as the player use it | 706 | // if we have the exact resolution as the player use it |
... | @@ -711,13 +709,21 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { | ... | @@ -711,13 +709,21 @@ videojs.HlsHandler.prototype.selectPlaylist = function () { |
711 | break; | 709 | break; |
712 | } else if (variant.attributes.RESOLUTION.width < width && | 710 | } else if (variant.attributes.RESOLUTION.width < width && |
713 | variant.attributes.RESOLUTION.height < height) { | 711 | variant.attributes.RESOLUTION.height < height) { |
714 | // if we don't have an exact match, see if we have a good higher quality variant to use | 712 | // if both dimensions are less than the player use the |
715 | if (oldvariant && oldvariant.attributes && oldvariant.attributes.RESOLUTION && | 713 | // previous (next-largest) variant |
716 | oldvariant.attributes.RESOLUTION.width && oldvariant.attributes.RESOLUTION.height) { | ||
717 | resolutionPlusOne = oldvariant; | ||
718 | } | ||
719 | resolutionBestVariant = variant; | ||
720 | break; | 714 | break; |
715 | } else if (!resolutionPlusOne || | ||
716 | (variant.attributes.RESOLUTION.width < resolutionPlusOne.attributes.RESOLUTION.width && | ||
717 | variant.attributes.RESOLUTION.height < resolutionPlusOne.attributes.RESOLUTION.height)) { | ||
718 | // If we still haven't found a good match keep a | ||
719 | // reference to the previous variant for the next loop | ||
720 | // iteration | ||
721 | |||
722 | // By only saving variants if they are smaller than the | ||
723 | // previously saved variant, we ensure that we also pick | ||
724 | // the highest bandwidth variant that is just-larger-than | ||
725 | // the video player | ||
726 | resolutionPlusOne = variant; | ||
721 | } | 727 | } |
722 | } | 728 | } |
723 | 729 | ... | ... |
test/manifest/media2.m3u8
0 → 100644
... | @@ -496,9 +496,6 @@ test('calls `remove` on sourceBuffer to when loading a vod segment', function() | ... | @@ -496,9 +496,6 @@ test('calls `remove` on sourceBuffer to when loading a vod segment', function() |
496 | standardXHRResponse(requests[2]); | 496 | standardXHRResponse(requests[2]); |
497 | 497 | ||
498 | strictEqual(requests[0].url, 'manifest/master.m3u8', 'master playlist requested'); | 498 | strictEqual(requests[0].url, 'manifest/master.m3u8', 'master playlist requested'); |
499 | strictEqual(requests[1].url, | ||
500 | absoluteUrl('manifest/media3.m3u8'), | ||
501 | 'media playlist requested'); | ||
502 | equal(removes.length, 1, 'remove called'); | 499 | equal(removes.length, 1, 'remove called'); |
503 | deepEqual(removes[0], [0, 120 - 60], 'remove called with the right range'); | 500 | deepEqual(removes[0], [0, 120 - 60], 'remove called with the right range'); |
504 | }); | 501 | }); |
... | @@ -773,10 +770,10 @@ test('downloads media playlists after loading the master', function() { | ... | @@ -773,10 +770,10 @@ test('downloads media playlists after loading the master', function() { |
773 | 770 | ||
774 | strictEqual(requests[0].url, 'manifest/master.m3u8', 'master playlist requested'); | 771 | strictEqual(requests[0].url, 'manifest/master.m3u8', 'master playlist requested'); |
775 | strictEqual(requests[1].url, | 772 | strictEqual(requests[1].url, |
776 | absoluteUrl('manifest/media3.m3u8'), | 773 | absoluteUrl('manifest/media2.m3u8'), |
777 | 'media playlist requested'); | 774 | 'media playlist requested'); |
778 | strictEqual(requests[2].url, | 775 | strictEqual(requests[2].url, |
779 | absoluteUrl('manifest/media3-00001.ts'), | 776 | absoluteUrl('manifest/media2-00001.ts'), |
780 | 'first segment requested'); | 777 | 'first segment requested'); |
781 | }); | 778 | }); |
782 | 779 | ||
... | @@ -794,10 +791,10 @@ test('upshifts if the initial bandwidth hint is high', function() { | ... | @@ -794,10 +791,10 @@ test('upshifts if the initial bandwidth hint is high', function() { |
794 | 791 | ||
795 | strictEqual(requests[0].url, 'manifest/master.m3u8', 'master playlist requested'); | 792 | strictEqual(requests[0].url, 'manifest/master.m3u8', 'master playlist requested'); |
796 | strictEqual(requests[1].url, | 793 | strictEqual(requests[1].url, |
797 | absoluteUrl('manifest/media3.m3u8'), | 794 | absoluteUrl('manifest/media2.m3u8'), |
798 | 'media playlist requested'); | 795 | 'media playlist requested'); |
799 | strictEqual(requests[2].url, | 796 | strictEqual(requests[2].url, |
800 | absoluteUrl('manifest/media3-00001.ts'), | 797 | absoluteUrl('manifest/media2-00001.ts'), |
801 | 'first segment requested'); | 798 | 'first segment requested'); |
802 | }); | 799 | }); |
803 | 800 | ||
... | @@ -1133,7 +1130,10 @@ test('selects the correct rendition by player dimensions', function() { | ... | @@ -1133,7 +1130,10 @@ test('selects the correct rendition by player dimensions', function() { |
1133 | 1130 | ||
1134 | playlist = player.tech_.hls.selectPlaylist(); | 1131 | playlist = player.tech_.hls.selectPlaylist(); |
1135 | 1132 | ||
1136 | deepEqual(playlist.attributes.RESOLUTION, {width:960,height:540},'should return the correct resolution by player dimensions'); | 1133 | deepEqual(playlist.attributes.RESOLUTION, { |
1134 | width: 960, | ||
1135 | height:540 | ||
1136 | },'should return the correct resolution by player dimensions'); | ||
1137 | equal(playlist.attributes.BANDWIDTH, 1928000, 'should have the expected bandwidth in case of multiple'); | 1137 | equal(playlist.attributes.BANDWIDTH, 1928000, 'should have the expected bandwidth in case of multiple'); |
1138 | 1138 | ||
1139 | player.width(1920); | 1139 | player.width(1920); |
... | @@ -1158,6 +1158,15 @@ test('selects the correct rendition by player dimensions', function() { | ... | @@ -1158,6 +1158,15 @@ test('selects the correct rendition by player dimensions', function() { |
1158 | },'should return the correct resolution by player dimensions, if exact match'); | 1158 | },'should return the correct resolution by player dimensions, if exact match'); |
1159 | equal(playlist.attributes.BANDWIDTH, 440000, 'should have the expected bandwidth in case of multiple, if exact match'); | 1159 | equal(playlist.attributes.BANDWIDTH, 440000, 'should have the expected bandwidth in case of multiple, if exact match'); |
1160 | 1160 | ||
1161 | player.width(395); | ||
1162 | player.height(222); | ||
1163 | playlist = player.tech_.hls.selectPlaylist(); | ||
1164 | |||
1165 | deepEqual(playlist.attributes.RESOLUTION, { | ||
1166 | width:396, | ||
1167 | height:224 | ||
1168 | },'should return the next larger resolution by player dimensions, if no exact match exists'); | ||
1169 | equal(playlist.attributes.BANDWIDTH, 440000, 'should have the expected bandwidth in case of multiple, if exact match'); | ||
1161 | }); | 1170 | }); |
1162 | 1171 | ||
1163 | test('selects the highest bitrate playlist when the player dimensions are ' + | 1172 | test('selects the highest bitrate playlist when the player dimensions are ' + |
... | @@ -1498,7 +1507,7 @@ test('waits to download new segments until the media playlist is stable', functi | ... | @@ -1498,7 +1507,7 @@ test('waits to download new segments until the media playlist is stable', functi |
1498 | standardXHRResponse(requests.shift()); // media1 | 1507 | standardXHRResponse(requests.shift()); // media1 |
1499 | 1508 | ||
1500 | // force a playlist switch | 1509 | // force a playlist switch |
1501 | player.tech_.hls.playlists.media('media3.m3u8'); | 1510 | player.tech_.hls.playlists.media('media2.m3u8'); |
1502 | 1511 | ||
1503 | standardXHRResponse(requests.shift()); // segment 0 | 1512 | standardXHRResponse(requests.shift()); // segment 0 |
1504 | player.tech_.hls.sourceBuffer.trigger('updateend'); | 1513 | player.tech_.hls.sourceBuffer.trigger('updateend'); | ... | ... |
-
Please register or sign in to post a comment