Stats for nerds cleanup and fix linter errors
This commit is contained in:
parent
1da67594b6
commit
cd574be4e7
|
@ -25,7 +25,7 @@ function runApp() {
|
|||
label: 'Show Video Statistics',
|
||||
visible: parameters.mediaType === 'video',
|
||||
click: () => {
|
||||
browserWindow.webContents.send('showVideoStatistics', 'show')
|
||||
browserWindow.webContents.send('showVideoStatistics')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -11,7 +11,6 @@ import 'videojs-overlay/dist/videojs-overlay.css'
|
|||
import 'videojs-vtt-thumbnails-freetube'
|
||||
import 'videojs-contrib-quality-levels'
|
||||
import 'videojs-http-source-selector'
|
||||
import { ipcRenderer } from 'electron'
|
||||
|
||||
import { IpcChannels } from '../../../constants'
|
||||
|
||||
|
@ -85,6 +84,10 @@ export default Vue.extend({
|
|||
useHls: false,
|
||||
selectedDefaultQuality: '',
|
||||
selectedQuality: '',
|
||||
selectedResolution: '',
|
||||
selectedBitrate: '',
|
||||
selectedMimeType: '',
|
||||
selectedFPS: 0,
|
||||
using60Fps: false,
|
||||
maxFramerate: 0,
|
||||
activeSourceList: [],
|
||||
|
@ -92,6 +95,10 @@ export default Vue.extend({
|
|||
mouseTimeout: null,
|
||||
touchTimeout: null,
|
||||
lastTouchTime: null,
|
||||
playerStats: null,
|
||||
statsModal: null,
|
||||
showStatsModal: false,
|
||||
statsModalEventName: 'updateStats',
|
||||
dataSetup: {
|
||||
fluid: true,
|
||||
nativeTextTracks: false,
|
||||
|
@ -132,44 +139,8 @@ export default Vue.extend({
|
|||
2.25,
|
||||
2.5,
|
||||
2.75,
|
||||
3,
|
||||
3.25,
|
||||
3.5,
|
||||
3.75,
|
||||
4,
|
||||
4.25,
|
||||
4.5,
|
||||
4.75,
|
||||
5,
|
||||
5.25,
|
||||
5.5,
|
||||
5.75,
|
||||
6,
|
||||
6.25,
|
||||
6.5,
|
||||
6.75,
|
||||
7,
|
||||
7.25,
|
||||
7.5,
|
||||
7.75,
|
||||
8
|
||||
3
|
||||
]
|
||||
},
|
||||
stats: {
|
||||
videoId: '',
|
||||
playerResolution: null,
|
||||
frameInfo: null,
|
||||
volume: 0,
|
||||
bandwidth: null,
|
||||
bufferPercent: 0,
|
||||
fps: null,
|
||||
display: {
|
||||
modal: null,
|
||||
event: 'statsUpdated',
|
||||
keyboardShortcut: 'KeyI',
|
||||
rightClickEvent: 'showVideoStatistics',
|
||||
activated: false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -229,36 +200,11 @@ export default Vue.extend({
|
|||
|
||||
displayVideoPlayButton: function() {
|
||||
return this.$store.getters.getDisplayVideoPlayButton
|
||||
},
|
||||
formatted_stats: function() {
|
||||
let resolution = ''
|
||||
let dropFrame = ''
|
||||
if (this.stats.playerResolution != null) {
|
||||
resolution = `(${this.stats.playerResolution.height}X${this.stats.playerResolution.width}) @ ${this.stats.fps} ${this.$t('Video.Stats.fps')}`
|
||||
}
|
||||
if (this.stats.frameInfo != null) {
|
||||
dropFrame = `${this.stats.frameInfo.droppedVideoFrames} ${this.$t('Video.Stats.out of')} ${this.stats.frameInfo.totalVideoFrames}`
|
||||
}
|
||||
const stats = [
|
||||
[this.$t('Video.Stats.video id'), this.stats.videoId],
|
||||
[this.$t('Video.Stats.frame drop'), dropFrame],
|
||||
[this.$t('Video.Stats.player resolution'), resolution],
|
||||
[this.$t('Video.Stats.volume'), `${(this.stats.volume * 100).toFixed(0)} %`],
|
||||
[this.$t('Video.Stats.bandwidth'), `${(this.stats.bandwidth / 1000).toFixed(2)} Kbps`],
|
||||
[this.$t('Video.Stats.buffered'), `${(this.stats.bufferPercent * 100).toFixed(0)} %`]
|
||||
]
|
||||
|
||||
let formattedStats = '<ul style="list-style-type: none;text-align:left; padding-left:0px";>'
|
||||
for (const stat of stats) {
|
||||
formattedStats += `<li style="font-size: 75%">${stat[0]}: ${stat[1]}</li>`
|
||||
}
|
||||
formattedStats += '</ul>'
|
||||
return formattedStats
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedQuality: function() {
|
||||
this.currentFps()
|
||||
showStatsModal: function() {
|
||||
this.player.trigger(this.statsModalEventName)
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
|
@ -411,6 +357,7 @@ export default Vue.extend({
|
|||
this.player.on('ready', () => {
|
||||
this.$emit('ready')
|
||||
this.checkAspectRatio()
|
||||
this.createStatsModal()
|
||||
if (this.captionHybridList.length !== 0) {
|
||||
this.transformAndInsertCaptions()
|
||||
}
|
||||
|
@ -440,11 +387,36 @@ export default Vue.extend({
|
|||
}
|
||||
})
|
||||
|
||||
this.player.on(this.statsModalEventName, () => {
|
||||
if (this.showStatsModal) {
|
||||
this.statsModal.open()
|
||||
this.player.controls(true)
|
||||
this.statsModal.contentEl().innerHTML = this.getFormattedStats()
|
||||
} else {
|
||||
this.statsModal.close()
|
||||
}
|
||||
})
|
||||
|
||||
this.player.on('timeupdate', () => {
|
||||
if (this.format === 'dash') {
|
||||
this.playerStats = this.player.tech({ IWillNotUseThisInPlugins: true }).vhs.stats
|
||||
this.updateStatsContent()
|
||||
}
|
||||
})
|
||||
|
||||
this.player.textTrackSettings.on('modalclose', (_) => {
|
||||
const settings = this.player.textTrackSettings.getValues()
|
||||
this.updateDefaultCaptionSettings(JSON.stringify(settings))
|
||||
})
|
||||
this.addPlayerStatsEvent()
|
||||
|
||||
// right click menu
|
||||
if (this.usingElectron) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.removeAllListeners('showVideoStatistics')
|
||||
ipcRenderer.on('showVideoStatistics', (event) => {
|
||||
this.toggleShowStatsModal()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -851,6 +823,18 @@ export default Vue.extend({
|
|||
qualityElement.innerText = selectedQuality
|
||||
this.selectedQuality = selectedQuality
|
||||
|
||||
if (selectedQuality !== 'auto') {
|
||||
this.selectedResolution = `${adaptiveFormat.width}x${adaptiveFormat.height}`
|
||||
this.selectedFPS = adaptiveFormat.fps
|
||||
this.selectedBitrate = adaptiveFormat.bitrate
|
||||
this.selectedMimeType = adaptiveFormat.mimeType
|
||||
} else {
|
||||
this.selectedResolution = 'auto'
|
||||
this.selectedFPS = 'auto'
|
||||
this.selectedBitrate = 'auto'
|
||||
this.selectedMimeType = 'auto'
|
||||
}
|
||||
|
||||
const qualityItems = $('.quality-item').get()
|
||||
|
||||
$('.quality-item').removeClass('quality-selected')
|
||||
|
@ -1426,7 +1410,64 @@ export default Vue.extend({
|
|||
handleTouchEnd: function (event) {
|
||||
clearTimeout(this.touchPauseTimeout)
|
||||
},
|
||||
toggleShowStatsModal: function() {
|
||||
console.log(this.format)
|
||||
if (this.format !== 'dash') {
|
||||
this.showToast({
|
||||
message: 'Video statistics are not available for legacy videos'
|
||||
})
|
||||
} else {
|
||||
this.showStatsModal = !this.showStatsModal
|
||||
}
|
||||
},
|
||||
createStatsModal: function() {
|
||||
const ModalDialog = videojs.getComponent('ModalDialog')
|
||||
this.statsModal = new ModalDialog(this.player, {
|
||||
temporary: false,
|
||||
pauseOnOpen: false
|
||||
})
|
||||
this.player.addChild(this.statsModal)
|
||||
this.statsModal.el_.classList.add('statsModal')
|
||||
this.statsModal.on('modalclose', () => {
|
||||
this.showStatsModal = false
|
||||
})
|
||||
},
|
||||
updateStatsContent: function() {
|
||||
if (this.showStatsModal) {
|
||||
this.statsModal.contentEl().innerHTML = this.getFormattedStats()
|
||||
}
|
||||
},
|
||||
getFormattedStats: function() {
|
||||
const currentVolume = this.player.muted() ? 0 : this.player.volume()
|
||||
const volume = `${(currentVolume * 100).toFixed(0)}%`
|
||||
const bandwidth = `${(this.playerStats.bandwidth / 1000).toFixed(2)}kbps`
|
||||
const buffered = `${(this.player.bufferedPercent() * 100).toFixed(0)}%`
|
||||
const droppedFrames = this.playerStats.videoPlaybackQuality.droppedVideoFrames
|
||||
const totalFrames = this.playerStats.videoPlaybackQuality.totalVideoFrames
|
||||
const frames = `${droppedFrames} / ${totalFrames}`
|
||||
const resolution = `${this.selectedResolution}@${this.selectedFPS}fps`
|
||||
const playerDimensions = `${this.playerStats.playerDimensions.width}x${this.playerStats.playerDimensions.height}`
|
||||
const statsArray = [
|
||||
[this.$t('Video.Stats.Video ID'), this.videoId],
|
||||
[this.$t('Video.Stats.Resolution'), resolution],
|
||||
[this.$t('Video.Stats.Player Dimensions'), playerDimensions],
|
||||
[this.$t('Video.Stats.Bitrate'), this.selectedBitrate],
|
||||
[this.$t('Video.Stats.Volume'), volume],
|
||||
[this.$t('Video.Stats.Bandwidth'), bandwidth],
|
||||
[this.$t('Video.Stats.Buffered'), buffered],
|
||||
[this.$t('Video.Stats.Dropped / Total Frames'), frames],
|
||||
[this.$t('Video.Stats.Mimetype'), this.selectedMimeType]
|
||||
]
|
||||
let listContentHTML = ''
|
||||
|
||||
statsArray.forEach((stat) => {
|
||||
const content = `<p>${stat[0]}: ${stat[1]}</p>`
|
||||
listContentHTML += content
|
||||
})
|
||||
return listContentHTML
|
||||
},
|
||||
|
||||
// This function should always be at the bottom of this file
|
||||
keyboardShortcutHandler: function (event) {
|
||||
const activeInputs = $('.ft-input')
|
||||
|
||||
|
@ -1520,6 +1561,11 @@ export default Vue.extend({
|
|||
event.preventDefault()
|
||||
this.changeDurationBySeconds(this.defaultSkipInterval * 1)
|
||||
break
|
||||
case 73:
|
||||
// I Key
|
||||
event.preventDefault()
|
||||
this.toggleShowStatsModal()
|
||||
break
|
||||
case 49:
|
||||
// 1 Key
|
||||
// Jump to 10% in the video
|
||||
|
@ -1619,86 +1665,6 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
|
||||
addPlayerStatsEvent: function() {
|
||||
this.stats.videoId = this.videoId
|
||||
this.player.on('volumechange', () => {
|
||||
this.stats.volume = this.player.volume()
|
||||
this.player.trigger(this.stats.display.event)
|
||||
})
|
||||
|
||||
this.player.on('timeupdate', () => {
|
||||
const stats = this.player.tech({ IWillNotUseThisInPlugins: true }).vhs.stats
|
||||
this.stats.frameInfo = stats.videoPlaybackQuality
|
||||
this.player.trigger(this.stats.display.event)
|
||||
})
|
||||
|
||||
this.player.on('progress', () => {
|
||||
const stats = this.player.tech({ IWillNotUseThisInPlugins: true }).vhs.stats
|
||||
|
||||
this.stats.bandwidth = stats.bandwidth
|
||||
this.stats.bufferPercent = this.player.bufferedPercent()
|
||||
})
|
||||
|
||||
this.player.on('playerresize', () => {
|
||||
this.stats.playerResolution = this.player.currentDimensions()
|
||||
this.player.trigger(this.stats.display.event)
|
||||
})
|
||||
|
||||
this.createStatsModal()
|
||||
|
||||
this.player.on(this.stats.display.event, () => {
|
||||
if (this.stats.display.activated) {
|
||||
this.stats.display.modal.open()
|
||||
this.player.controls(true)
|
||||
this.stats.display.modal.contentEl().innerHTML = this.formatted_stats
|
||||
} else {
|
||||
this.stats.display.modal.close()
|
||||
}
|
||||
})
|
||||
// keyboard shortcut
|
||||
window.addEventListener('keyup', (event) => {
|
||||
if (event.code === this.stats.display.keyboardShortcut) {
|
||||
if (this.stats.display.activated) {
|
||||
this.deactivateStatsDisplay()
|
||||
} else {
|
||||
this.activateStatsDisplay()
|
||||
}
|
||||
}
|
||||
}, true)
|
||||
// right click menu
|
||||
ipcRenderer.on(this.stats.display.rightClickEvent, () => {
|
||||
this.activateStatsDisplay()
|
||||
})
|
||||
},
|
||||
createStatsModal: function() {
|
||||
const ModalDialog = videojs.getComponent('ModalDialog')
|
||||
this.stats.display.modal = new ModalDialog(this.player, {
|
||||
temporary: false,
|
||||
pauseOnOpen: false
|
||||
})
|
||||
this.player.addChild(this.stats.display.modal)
|
||||
this.stats.display.modal.height('35%')
|
||||
this.stats.display.modal.width('50%')
|
||||
this.stats.display.modal.contentEl().style.backgroundColor = 'rgba(0, 0, 0, 0.55)'
|
||||
this.stats.display.modal.on('modalclose', () => {
|
||||
this.deactivateStatsDisplay()
|
||||
})
|
||||
},
|
||||
activateStatsDisplay: function() {
|
||||
this.stats.display.activated = true
|
||||
},
|
||||
deactivateStatsDisplay: function() {
|
||||
this.stats.display.activated = false
|
||||
},
|
||||
currentFps: function() {
|
||||
for (const el of this.activeAdaptiveFormats) {
|
||||
if (el.qualityLabel === this.selectedQuality) {
|
||||
this.stats.fps = el.fps
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'calculateColorLuminance',
|
||||
'updateDefaultCaptionSettings',
|
||||
|
|
|
@ -4,7 +4,6 @@ import fs from 'fs'
|
|||
import i18n from '../../i18n/index'
|
||||
|
||||
import { IpcChannels } from '../../../constants'
|
||||
import { ipcRenderer } from 'electron'
|
||||
|
||||
const state = {
|
||||
isSideNavOpen: false,
|
||||
|
@ -223,8 +222,6 @@ const actions = {
|
|||
})
|
||||
|
||||
const reader = response.body.getReader()
|
||||
const contentLength = response.headers.get('Content-Length')
|
||||
let receivedLength = 0
|
||||
const chunks = []
|
||||
|
||||
const handleError = (err) => {
|
||||
|
@ -240,9 +237,10 @@ const actions = {
|
|||
}
|
||||
|
||||
chunks.push(value)
|
||||
receivedLength += value.length
|
||||
// Can be used in the future to determine download percentage
|
||||
const percentage = receivedLength / contentLength
|
||||
// const contentLength = response.headers.get('Content-Length')
|
||||
// const receivedLength = value.length
|
||||
// const percentage = receivedLength / contentLength
|
||||
await reader.read().then(processText).catch(handleError)
|
||||
}
|
||||
|
||||
|
|
|
@ -2160,3 +2160,24 @@ video::-webkit-media-text-track-display {
|
|||
font-size: xx-large;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.vjs-modal-dialog.statsModal {
|
||||
line-height: 10px;
|
||||
width: 550px;
|
||||
height: 225px;
|
||||
font-size: 10px;
|
||||
background-color: rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
.vjs-modal-dialog.statsModal p {
|
||||
line-height: 10px;
|
||||
position:relative;
|
||||
bottom: 15px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 775px) {
|
||||
.vjs-modal-dialog.statsModal {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -556,14 +556,15 @@ Video:
|
|||
shuffling playlists: shuffling playlists
|
||||
looping playlists: looping playlists
|
||||
Stats:
|
||||
video id: "Video ID (YouTube)"
|
||||
player resolution: "Viewport"
|
||||
volume: "Volume"
|
||||
fps: "FPS"
|
||||
frame drop: "Frame Drop"
|
||||
bandwidth: "Connection Speed"
|
||||
buffered: "Buffered"
|
||||
out of: "out of"
|
||||
Video ID: Video ID
|
||||
Resolution: Resolution
|
||||
Player Dimensions: Player Dimensions
|
||||
Bitrate: Bitrate
|
||||
Volume: Volume
|
||||
Bandwidth: Bandwidth
|
||||
Buffered: Buffered
|
||||
Dropped / Total Frames: Dropped / Total Frames
|
||||
Mimetype: Mimetype
|
||||
#& Videos
|
||||
Videos:
|
||||
#& Sort By
|
||||
|
|
Loading…
Reference in New Issue