Fix quality logic again

This commit is contained in:
Preston 2021-05-15 15:08:41 -04:00
parent cd38847f0a
commit 176d81dd6b
6 changed files with 123 additions and 41 deletions

36
package-lock.json generated
View File

@ -3560,12 +3560,12 @@
} }
}, },
"@silvermine/videojs-quality-selector": { "@silvermine/videojs-quality-selector": {
"version": "1.2.4", "version": "1.2.5",
"resolved": "https://registry.npmjs.org/@silvermine/videojs-quality-selector/-/videojs-quality-selector-1.2.4.tgz", "resolved": "https://registry.npmjs.org/@silvermine/videojs-quality-selector/-/videojs-quality-selector-1.2.5.tgz",
"integrity": "sha512-bLCoOk2kEhebXjuREMIjCqM1ZYQOnIJ8/McF2NcTsK6RluuHUSnFzZrH98sWkHGOTNrt+g9m27+kLlR6+x5jYg==", "integrity": "sha512-cielchUzL8r2EX01S7PfR54tTbxDZR53xIDJoUi9Wg6pM2X+ftdJD6XiIDVOjPlBoG94iuG9LJwUtjX5IhrWZQ==",
"requires": { "requires": {
"class.extend": "0.9.1", "class.extend": "0.9.1",
"underscore": "1.9.1" "underscore": "1.13.1"
} }
}, },
"@sindresorhus/is": { "@sindresorhus/is": {
@ -12769,12 +12769,6 @@
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
}, },
"nanoid": {
"version": "3.1.20",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
"dev": true
},
"nanomatch": { "nanomatch": {
"version": "1.2.13", "version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@ -14064,16 +14058,22 @@
"dev": true "dev": true
}, },
"postcss": { "postcss": {
"version": "8.2.6", "version": "8.2.15",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.6.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.15.tgz",
"integrity": "sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg==", "integrity": "sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"colorette": "^1.2.1", "colorette": "^1.2.2",
"nanoid": "^3.1.20", "nanoid": "^3.1.23",
"source-map": "^0.6.1" "source-map": "^0.6.1"
}, },
"dependencies": { "dependencies": {
"nanoid": {
"version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
"dev": true
},
"source-map": { "source-map": {
"version": "0.6.1", "version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -16588,9 +16588,9 @@
"dev": true "dev": true
}, },
"underscore": { "underscore": {
"version": "1.9.1", "version": "1.13.1",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
"integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g=="
}, },
"unicode-canonical-property-names-ecmascript": { "unicode-canonical-property-names-ecmascript": {
"version": "1.0.4", "version": "1.0.4",

View File

@ -13,7 +13,7 @@
"@fortawesome/free-brands-svg-icons": "^5.15.2", "@fortawesome/free-brands-svg-icons": "^5.15.2",
"@fortawesome/free-solid-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.2",
"@fortawesome/vue-fontawesome": "^2.0.2", "@fortawesome/vue-fontawesome": "^2.0.2",
"@silvermine/videojs-quality-selector": "^1.2.4", "@silvermine/videojs-quality-selector": "^1.2.5",
"autolinker": "^3.14.2", "autolinker": "^3.14.2",
"bulma-pro": "^0.2.0", "bulma-pro": "^0.2.0",
"dateformat": "^4.5.1", "dateformat": "^4.5.1",

View File

@ -43,6 +43,10 @@ export default Vue.extend({
type: Array, type: Array,
default: () => { return [] } default: () => { return [] }
}, },
adaptiveFormats: {
type: Array,
default: () => { return [] }
},
dashSrc: { dashSrc: {
type: Array, type: Array,
default: null default: null
@ -77,6 +81,7 @@ export default Vue.extend({
using60Fps: false, using60Fps: false,
maxFramerate: 0, maxFramerate: 0,
activeSourceList: [], activeSourceList: [],
activeAdaptiveFormats: [],
mouseTimeout: null, mouseTimeout: null,
touchTimeout: null, touchTimeout: null,
lastTouchTime: null, lastTouchTime: null,
@ -178,6 +183,7 @@ export default Vue.extend({
}, },
methods: { methods: {
initializePlayer: async function () { initializePlayer: async function () {
console.log(this.adaptiveFormats)
const videoPlayer = document.getElementById(this.id) const videoPlayer = document.getElementById(this.id)
if (videoPlayer !== null) { if (videoPlayer !== null) {
if (!this.useDash) { if (!this.useDash) {
@ -416,7 +422,28 @@ export default Vue.extend({
this.setDashQualityLevel('auto') this.setDashQualityLevel('auto')
} }
this.player.qualityLevels().levels_.sort((a, b) => { let formatsToTest = this.activeAdaptiveFormats.filter((format) => {
return format.height === this.defaultQuality
})
if (formatsToTest.length === 0) {
formatsToTest = this.activeAdaptiveFormats.filter((format) => {
return format.height < this.defaultQuality
})
}
formatsToTest = formatsToTest.sort((a, b) => {
if (a.height === b.height) {
return b.bitrate - a.bitrate
} else {
return b.height - a.height
}
})
this.setDashQualityLevel(formatsToTest[0].bitrate)
// Old logic. Revert if needed
/* this.player.qualityLevels().levels_.sort((a, b) => {
if (a.height === b.height) { if (a.height === b.height) {
return a.bitrate - b.bitrate return a.bitrate - b.bitrate
} else { } else {
@ -449,11 +476,52 @@ export default Vue.extend({
} else if (index === (arr.length - 1) && quality < this.defaultQuality) { } else if (index === (arr.length - 1) && quality < this.defaultQuality) {
this.setDashQualityLevel(height) this.setDashQualityLevel(height)
} }
}) }) */
}, },
setDashQualityLevel: function (qualityLevel, is60Fps = false) { setDashQualityLevel: function (bitrate) {
if (this.selectedQuality === qualityLevel && this.using60Fps === is60Fps) { let adaptiveFormat = null
if (bitrate !== 'auto') {
adaptiveFormat = this.activeAdaptiveFormats.find((format) => {
return format.bitrate === bitrate
})
}
this.player.qualityLevels().levels_.sort((a, b) => {
if (a.height === b.height) {
return a.bitrate - b.bitrate
} else {
return a.height - b.height
}
}).forEach((ql, index, arr) => {
if (bitrate === 'auto' || bitrate === ql.bitrate) {
ql.enabled = true
ql.enabled_(true)
} else {
ql.enabled = false
ql.enabled_(false)
}
})
const selectedQuality = bitrate === 'auto' ? 'auto' : adaptiveFormat.qualityLabel
const qualityElement = document.getElementById('vjs-current-quality')
qualityElement.innerText = selectedQuality
this.selectedQuality = selectedQuality
const qualityItems = $('.quality-item').get()
$('.quality-item').removeClass('quality-selected')
qualityItems.forEach((item) => {
const qualityText = $(item).find('.vjs-menu-item-text').get(0)
if (qualityText.innerText === selectedQuality.toLowerCase()) {
$(item).addClass('quality-selected')
}
})
/* if (this.selectedQuality === qualityLevel && this.using60Fps === is60Fps) {
return return
} }
let foundSelectedQuality = false let foundSelectedQuality = false
@ -530,7 +598,7 @@ export default Vue.extend({
// const currentTime = this.player.currentTime() // const currentTime = this.player.currentTime()
// this.player.currentTime(0) // this.player.currentTime(0)
// this.player.currentTime(currentTime) // this.player.currentTime(currentTime) */
}, },
enableDashFormat: function () { enableDashFormat: function () {
@ -725,10 +793,10 @@ export default Vue.extend({
VjsButton.call(this, player, options) VjsButton.call(this, player, options)
}, },
handleClick: function(event) { handleClick: function(event) {
console.log(event)
const selectedQuality = event.target.innerText const selectedQuality = event.target.innerText
const quality = selectedQuality === 'auto' ? 'auto' : parseInt(selectedQuality.replace('p(60)?', '')) const bitrate = selectedQuality === 'auto' ? 'auto' : parseInt(event.target.attributes.bitrate.value)
const is60Fps = selectedQuality.includes('p60') v.setDashQualityLevel(bitrate)
v.setDashQualityLevel(quality, is60Fps)
}, },
createControlTextEl: function (button) { createControlTextEl: function (button) {
const beginningHtml = `<div class="vjs-quality-level-value"> const beginningHtml = `<div class="vjs-quality-level-value">
@ -738,7 +806,7 @@ export default Vue.extend({
<ul class="vjs-menu-content" role="menu">` <ul class="vjs-menu-content" role="menu">`
const endingHtml = '</ul></div>' const endingHtml = '</ul></div>'
let qualityHtml = `<li class="vjs-menu-item quality-item" role="menuitemradio" tabindex="-1" aria-checked="false aria-disabled="false"> let qualityHtml = `<li class="vjs-menu-item quality-item" role="menuitemradio" tabindex="-1" aria-checked="false" aria-disabled="false">
<span class="vjs-menu-item-text">Auto</span> <span class="vjs-menu-item-text">Auto</span>
<span class="vjs-control-text" aria-live="polite"></span> <span class="vjs-control-text" aria-live="polite"></span>
</li>` </li>`
@ -750,7 +818,23 @@ export default Vue.extend({
return b.height - a.height return b.height - a.height
} }
}).forEach((quality, index, array) => { }).forEach((quality, index, array) => {
let is60Fps = false const adaptiveFormat = v.adaptiveFormats.find((format) => {
return format.bitrate === quality.bitrate
})
v.activeAdaptiveFormats.push(adaptiveFormat)
const fps = adaptiveFormat.fps
const qualityLabel = adaptiveFormat.qualityLabel
const bitrate = quality.bitrate
qualityHtml = qualityHtml + `<li class="vjs-menu-item quality-item" role="menuitemradio" tabindex="-1" aria-checked="false" aria-disabled="false" fps="${fps}" bitrate="${bitrate}">
<span class="vjs-menu-item-text" fps="${fps}" bitrate="${bitrate}">${qualityLabel}</span>
<span class="vjs-control-text" aria-live="polite"></span>
</li>`
// Old logic, revert if needed.
/* let is60Fps = false
if (index < array.length - 1 && array[index + 1].height === quality.height) { if (index < array.length - 1 && array[index + 1].height === quality.height) {
if (array[index + 1].bitrate < quality.bitrate) { if (array[index + 1].bitrate < quality.bitrate) {
is60Fps = true is60Fps = true
@ -760,7 +844,7 @@ export default Vue.extend({
qualityHtml = qualityHtml + `<li class="vjs-menu-item quality-item" role="menuitemradio" tabindex="-1" aria-checked="false aria-disabled="false"> qualityHtml = qualityHtml + `<li class="vjs-menu-item quality-item" role="menuitemradio" tabindex="-1" aria-checked="false aria-disabled="false">
<span class="vjs-menu-item-text">${qualityText}</span> <span class="vjs-menu-item-text">${qualityText}</span>
<span class="vjs-control-text" aria-live="polite"></span> <span class="vjs-control-text" aria-live="polite"></span>
</li>` </li>` */
}) })
return $(button).html( return $(button).html(
$(beginningHtml + qualityHtml + endingHtml).attr( $(beginningHtml + qualityHtml + endingHtml).attr(

View File

@ -664,10 +664,10 @@ body.vjs-full-window {
display: none; display: none;
position: absolute; position: absolute;
bottom: 30px; bottom: 30px;
left: -15px; left: -33px;
z-index: 5; z-index: 5;
background-color: #151b17; background-color: #151b17;
width: 70px; width: 100px;
max-height: 225px; max-height: 225px;
overflow-y: auto; overflow-y: auto;
} }

View File

@ -69,6 +69,7 @@ export default Vue.extend({
activeSourceList: [], activeSourceList: [],
videoSourceList: [], videoSourceList: [],
audioSourceList: [], audioSourceList: [],
adaptiveFormats: [],
captionHybridList: [], // [] -> Promise[] -> string[] (URIs) captionHybridList: [], // [] -> Promise[] -> string[] (URIs)
recommendedVideos: [], recommendedVideos: [],
downloadLinks: [], downloadLinks: [],
@ -291,7 +292,7 @@ export default Vue.extend({
this.videoLikeCount = isNaN(result.videoDetails.likes) ? 0 : result.videoDetails.likes this.videoLikeCount = isNaN(result.videoDetails.likes) ? 0 : result.videoDetails.likes
this.videoDislikeCount = isNaN(result.videoDetails.dislikes) ? 0 : result.videoDetails.dislikes this.videoDislikeCount = isNaN(result.videoDetails.dislikes) ? 0 : result.videoDetails.dislikes
} }
this.isLive = result.player_response.videoDetails.isLive || result.player_response.videoDetails.isLiveContent this.isLive = result.player_response.videoDetails.isLive
this.isLiveContent = result.player_response.videoDetails.isLiveContent this.isLiveContent = result.player_response.videoDetails.isLiveContent
this.isUpcoming = result.player_response.videoDetails.isUpcoming ? result.player_response.videoDetails.isUpcoming : false this.isUpcoming = result.player_response.videoDetails.isUpcoming ? result.player_response.videoDetails.isUpcoming : false
@ -311,7 +312,7 @@ export default Vue.extend({
} }
} }
if (this.isLive && !this.isUpcoming) { if ((this.isLive || this.isLiveContent) && !this.isUpcoming) {
this.enableLegacyFormat() this.enableLegacyFormat()
this.videoSourceList = result.formats.filter((format) => { this.videoSourceList = result.formats.filter((format) => {
@ -364,6 +365,7 @@ export default Vue.extend({
} else { } else {
this.videoSourceList = result.player_response.streamingData.adaptiveFormats.reverse() this.videoSourceList = result.player_response.streamingData.adaptiveFormats.reverse()
} }
this.adaptiveFormats = this.videoSourceList
this.downloadLinks = result.formats.filter((format) => { this.downloadLinks = result.formats.filter((format) => {
return typeof format.mimeType !== 'undefined' return typeof format.mimeType !== 'undefined'
}).map((format) => { }).map((format) => {
@ -434,14 +436,9 @@ export default Vue.extend({
if (this.proxyVideos) { if (this.proxyVideos) {
this.dashSrc = await this.createInvidiousDashManifest() this.dashSrc = await this.createInvidiousDashManifest()
} else { } else {
const adaptiveFormats = result.player_response.streamingData.adaptiveFormats.filter((video) => { const adaptiveFormats = result.player_response.streamingData.adaptiveFormats
if (typeof (video.qualityLabel) !== 'undefined') {
return !video.qualityLabel.includes('HDR')
} else {
return true
}
})
this.dashSrc = await this.createLocalDashManifest(adaptiveFormats) this.dashSrc = await this.createLocalDashManifest(adaptiveFormats)
this.adaptiveFormats = adaptiveFormats
} }
this.audioSourceList = result.player_response.streamingData.adaptiveFormats.filter((format) => { this.audioSourceList = result.player_response.streamingData.adaptiveFormats.filter((format) => {

View File

@ -18,6 +18,7 @@
ref="videoPlayer" ref="videoPlayer"
:dash-src="dashSrc" :dash-src="dashSrc"
:source-list="activeSourceList" :source-list="activeSourceList"
:adaptive-formats="adaptiveFormats"
:caption-hybrid-list="captionHybridList" :caption-hybrid-list="captionHybridList"
:storyboard-src="videoStoryboardSrc" :storyboard-src="videoStoryboardSrc"
:format="activeFormat" :format="activeFormat"