private readonly playerElement: HTMLVideoElement
private readonly autoplay: boolean = false
+ private readonly startTime: number = 0
private readonly savePlayerSrcFunction: Function
private readonly videoFiles: VideoFile[]
private readonly videoViewUrl: string
INFO_SCHEDULER: 1000, // Don't change this
AUTO_QUALITY_SCHEDULER: 3000, // Check quality every 3 seconds
AUTO_QUALITY_THRESHOLD_PERCENT: 30, // Bandwidth should be 30% more important than a resolution bitrate to change to it
- AUTO_QUALITY_OBSERVATION_TIME: 10000, // Wait 10 seconds before potentially changing the definition
- AUTO_QUALITY_UPPER_RESOLUTION_DELAY: 5000, // Buffer upper resolution during 5 seconds
+ AUTO_QUALITY_OBSERVATION_TIME: 10000, // Wait 10 seconds after having change the resolution before another check
+ AUTO_QUALITY_HIGHER_RESOLUTION_DELAY: 5000, // Buffering higher resolution during 5 seconds
BANDWIDTH_AVERAGE_NUMBER_OF_VALUES: 5 // Last 5 seconds to build average bandwidth
}
private player: any
private currentVideoFile: VideoFile
private torrent: WebTorrent.Torrent
+ private autoResolution = true
+ private isAutoResolutionObservation = false
+
private videoViewInterval
private torrentInfoInterval
private autoQualityInterval
- private autoResolution = true
- private isAutoResolutionObservation = false
+ private addTorrentDelay
+ private qualityObservationTimer
+ private runAutoQualitySchedulerTimer
private downloadSpeeds: number[] = []
constructor (player: videojs.Player, options: PeertubePluginOptions) {
super(player, options)
- // Fix canplay event on google chrome by disabling default videojs autoplay
- this.autoplay = this.player.options_.autoplay
- this.player.options_.autoplay = false
+ this.autoplay = options.autoplay
+ this.startTime = options.startTime
this.videoFiles = options.videoFiles
this.videoViewUrl = options.videoViewUrl
this.videoDuration = options.videoDuration
this.playerElement = options.playerElement
+ if (this.autoplay === true) this.player.addClass('vjs-has-autoplay')
+
this.player.ready(() => {
const volume = getStoredVolume()
if (volume !== undefined) this.player.volume(volume)
this.runViewAdd()
this.player.one('play', () => {
- // Don't run immediately scheduler, wait some seconds the TCP connections are maid
- setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER)
+ // Don't run immediately scheduler, wait some seconds the TCP connections are made
+ this.runAutoQualitySchedulerTimer = setTimeout(() => {
+ this.runAutoQualityScheduler()
+ }, this.CONSTANTS.AUTO_QUALITY_SCHEDULER)
})
})
}
dispose () {
+ clearTimeout(this.addTorrentDelay)
+ clearTimeout(this.qualityObservationTimer)
+ clearTimeout(this.runAutoQualitySchedulerTimer)
+
clearInterval(this.videoViewInterval)
clearInterval(this.torrentInfoInterval)
clearInterval(this.autoQualityInterval)
oldTorrent.removePeer(oldTorrent['ws'])
}
- setTimeout(() => {
+ this.addTorrentDelay = setTimeout(() => {
this.flushVideoFile(previousVideoFile)
const options = { autoplay: true, controls: true }
if (err) return this.fallbackToHttp(done)
- if (!this.player.paused()) {
- const playPromise = this.player.play()
- if (playPromise !== undefined) return playPromise.then(done)
-
- return done()
- }
+ if (!this.player.paused()) return this.tryToPlay(done)
return done()
})
}
const newVideoFile = this.videoFiles.find(f => f.resolution.id === resolutionId)
- this.updateVideoFile(newVideoFile, delay, () => {
- this.player.currentTime(currentTime)
- this.player.handleTechSeeked_()
- })
+ this.updateVideoFile(newVideoFile, delay, () => this.seek(currentTime))
}
flushVideoFile (videoFile: VideoFile, destroyRenderer = true) {
this.trigger('autoResolutionUpdate')
}
+ private tryToPlay (done?: Function) {
+ if (!done) done = function () { /* empty */ }
+
+ const playPromise = this.player.play()
+ if (playPromise !== undefined) {
+ return playPromise.then(done)
+ .catch(err => {
+ console.error(err)
+ this.player.pause()
+ this.player.posterImage.show()
+ this.player.removeClass('vjs-has-autoplay')
+
+ return done()
+ })
+ }
+
+ return done()
+ }
+
+ private seek (time: number) {
+ this.player.currentTime(time)
+ this.player.handleTechSeeked_()
+ }
+
private getAppropriateFile (averageDownloadSpeed?: number): VideoFile {
if (this.videoFiles === undefined || this.videoFiles.length === 0) return undefined
if (this.videoFiles.length === 1) return this.videoFiles[0]
const fileBitrate = (f.size / this.videoDuration)
let threshold = fileBitrate
- // If this is for a higher resolution, or an initial load -> add a upper margin
+ // If this is for a higher resolution or an initial load: add a margin
if (!this.currentVideoFile || f.resolution.id > this.currentVideoFile.resolution.id) {
threshold += ((fileBitrate * this.CONSTANTS.AUTO_QUALITY_THRESHOLD_PERCENT) / 100)
}
if (this.autoplay === true) {
this.player.posterImage.hide()
- this.updateVideoFile(undefined, 0, () => this.player.play())
+
+ this.updateVideoFile(undefined, 0, () => {
+ this.seek(this.startTime)
+ this.tryToPlay()
+ })
} else {
// Proxy first play
const oldPlay = this.player.play.bind(this.player)
this.player.play = () => {
- this.updateVideoFile(undefined, 0, () => oldPlay)
+ this.player.addClass('vjs-has-big-play-button-clicked')
this.player.play = oldPlay
+
+ this.updateVideoFile(undefined, 0, () => this.seek(this.startTime))
}
}
}
private runAutoQualityScheduler () {
this.autoQualityInterval = setInterval(() => {
- if (this.torrent === undefined) return
+
+ // Not initialized or in HTTP fallback
+ if (this.torrent === undefined || this.torrent === null) return
if (this.isAutoResolutionOn() === false) return
if (this.isAutoResolutionObservation === true) return
if (this.isPlayerWaiting() && file.resolution.id < this.currentVideoFile.resolution.id) {
console.log('Downgrading automatically the resolution to: %s', file.resolution.label)
changeResolution = true
- } else if (file.resolution.id > this.currentVideoFile.resolution.id) { // Greater resolution
+ } else if (file.resolution.id > this.currentVideoFile.resolution.id) { // Higher resolution
console.log('Upgrading automatically the resolution to: %s', file.resolution.label)
changeResolution = true
- changeResolutionDelay = this.CONSTANTS.AUTO_QUALITY_UPPER_RESOLUTION_DELAY
+ changeResolutionDelay = this.CONSTANTS.AUTO_QUALITY_HIGHER_RESOLUTION_DELAY
}
if (changeResolution === true) {
// Wait some seconds in observation of our new resolution
this.isAutoResolutionObservation = true
- setTimeout(() => this.isAutoResolutionObservation = false, this.CONSTANTS.AUTO_QUALITY_OBSERVATION_TIME)
+
+ this.qualityObservationTimer = setTimeout(() => {
+ this.isAutoResolutionObservation = false
+ }, this.CONSTANTS.AUTO_QUALITY_OBSERVATION_TIME)
}
}, this.CONSTANTS.AUTO_QUALITY_SCHEDULER)
}
private isPlayerWaiting () {
- return this.player.hasClass('vjs-waiting')
+ return this.player && this.player.hasClass('vjs-waiting')
}
private runTorrentInfoScheduler () {