Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | 28x 5x 2x 3x 3x 3x 3x 3x 8x 8x 2x 2x 3x | /* * cap stream level to media size dimension controller */ import Event from '../events'; import EventHandler from '../event-handler'; class CapLevelController extends EventHandler { constructor (hls) { super(hls, Event.FPS_DROP_LEVEL_CAPPING, Event.MEDIA_ATTACHING, Event.MANIFEST_PARSED); } destroy () { if (this.hls.config.capLevelToPlayerSize) { this.media = this.restrictedLevels = null; this.autoLevelCapping = Number.POSITIVE_INFINITY; if (this.timer) this.timer = clearInterval(this.timer); } } onFpsDropLevelCapping (data) { // Don't add a restricted level more than once if (CapLevelController.isLevelAllowed(data.droppedLevel, this.restrictedLevels)) this.restrictedLevels.push(data.droppedLevel); } onMediaAttaching (data) { this.media = data.media instanceof HTMLVideoElement ? data.media : null; } onManifestParsed (data) { const hls = this.hls; this.restrictedLevels = []; if (hls.config.capLevelToPlayerSize) { this.autoLevelCapping = Number.POSITIVE_INFINITY; this.levels = data.levels; hls.firstLevel = this.getMaxLevel(data.firstLevel); clearInterval(this.timer); this.timer = setInterval(this.detectPlayerSize.bind(this), 1000); this.detectPlayerSize(); } } detectPlayerSize () { if (this.media) { let levelsLength = this.levels ? this.levels.length : 0; if (levelsLength) { const hls = this.hls; hls.autoLevelCapping = this.getMaxLevel(levelsLength - 1); if (hls.autoLevelCapping > this.autoLevelCapping) { // if auto level capping has a higher value for the previous one, flush the buffer using nextLevelSwitch // usually happen when the user go to the fullscreen mode. hls.streamController.nextLevelSwitch(); } this.autoLevelCapping = hls.autoLevelCapping; } } } /* * returns level should be the one with the dimensions equal or greater than the media (player) dimensions (so the video will be downscaled) */ getMaxLevel (capLevelIndex) { if (!this.levels) return -1; const validLevels = this.levels.filter((level, index) => CapLevelController.isLevelAllowed(index, this.restrictedLevels) && index <= capLevelIndex ); return CapLevelController.getMaxLevelByMediaSize(validLevels, this.mediaWidth, this.mediaHeight); } get mediaWidth () { let width; const media = this.media; if (media) { width = media.width || media.clientWidth || media.offsetWidth; width *= CapLevelController.contentScaleFactor; } return width; } get mediaHeight () { let height; const media = this.media; if (media) { height = media.height || media.clientHeight || media.offsetHeight; height *= CapLevelController.contentScaleFactor; } return height; } static get contentScaleFactor () { let pixelRatio = 1; try { pixelRatio = window.devicePixelRatio; } catch (e) {} return pixelRatio; } static isLevelAllowed (level, restrictedLevels = []) { return restrictedLevels.indexOf(level) === -1; } static getMaxLevelByMediaSize (levels, width, height) { if (!levels || (levels && !levels.length)) return -1; // Levels can have the same dimensions but differing bandwidths - since levels are ordered, we can look to the next // to determine whether we've chosen the greatest bandwidth for the media's dimensions const atGreatestBandiwdth = (curLevel, nextLevel) => { Iif (!nextLevel) return true; return curLevel.width !== nextLevel.width || curLevel.height !== nextLevel.height; }; // If we run through the loop without breaking, the media's dimensions are greater than every level, so default to // the max level let maxLevelIndex = levels.length - 1; for (let i = 0; i < levels.length; i += 1) { const level = levels[i]; if ((level.width >= width || level.height >= height) && atGreatestBandiwdth(level, levels[i + 1])) { maxLevelIndex = i; break; } } return maxLevelIndex; } } export default CapLevelController; |