使用此代码是否可行: jwplayer()。getQualityLevels()
答案 0 :(得分:0)
根据您的问题,我认为您没有使用HLS或DASH,而是您有几个MP4以不同的比特率或分辨率编码。 MP4需要正确编码以支持渐进式下载,http服务器需要支持字节范围的标头。可以监视jwplayer的缓冲区,当它变得太低时,您可以切换到质量较低的源。我们这样做www.scormfly.com。这里有一些可以帮助你入门的打字稿代码。
import * as _ from 'lodash'
import Controls, { StreamingMode } from '../controls'
const controls = new Controls()
export default class ProgressiveDownloadProvider {
private positionBeforeQualityChange = 0
private isSeeking: boolean
private jwplayer: JWPlayer
constructor(jwplayer: JWPlayer) {
jwplayer.on('levels', this.setToBestFitQuality)
jwplayer.on('levelsChanged', this.onQualityChange)
jwplayer.on('time', this.tick)
this.jwplayer = jwplayer
}
public tick(args: TimeParam) {
if (this.isQualityTooHigh(args.position)) {
this.reduceQualityLevel()
}
}
public onResize() {
// don't change the quality unless the the video is playing
// because changing the quality will start playing the video
if (this.jwplayer.getState().toUpperCase() === 'PLAYING') {
this.setToBestFitQuality()
}
}
private isQualityTooHigh(currentPosition: number): boolean {
if (this.isSeeking) { return false }
if (currentPosition < this.positionBeforeQualityChange + 1) { return false }
const videoElement = $('video')[0]
const bufferPositionInSeconds = videoElement ?
(videoElement as any).buffered.end((videoElement as any).buffered.length - 1) :
this.jwplayer.getBuffer() / 100.0 * controls.getDuration()
const bufferAlmostComplete = bufferPositionInSeconds > controls.getDuration() - 10
if (bufferAlmostComplete) { return false }
const bufferRunningLow = bufferPositionInSeconds - currentPosition < 0.5
return bufferRunningLow
}
private reduceQualityLevel() {
// qualityLevels are indexed 0-best to 5-worst quality
const qualityLevels = this.jwplayer.getQualityLevels()
const indexOfWorstQuality = qualityLevels.length - 1
const indexOfCurrentQuality = this.jwplayer.getCurrentQuality()
if (indexOfCurrentQuality === indexOfWorstQuality) { return }
// tslint:disable-next-line:no-console
console.log('reducing quality from '
+ qualityLevels[indexOfCurrentQuality].label + ' to '
+ qualityLevels[indexOfCurrentQuality + 1].label + ' due to buffering')
this.jwplayer.setCurrentQuality(indexOfCurrentQuality + 1)
}
// detect viewport height and use the best fitting source
private setToBestFitQuality() {
if (controls.getStreamingMode() === StreamingMode.YouTube) { return } // don't adjust youtube videos
if (typeof this.jwplayer.getQualityLevels() === 'undefined') { return } // not ready yet
if (this.jwplayer.getQualityLevels().length === 0) { return } // nothing to do
if (this.jwplayer.getCurrentQuality() === -1) { return } // this can happen onComplete
const newHeight = $('#jwPlayer').height()
const currentQuality = this.jwplayer.getQualityLevels()[this.jwplayer.getCurrentQuality()].label // eg 720p HD
let optimalQuality: string
const heights = _.map(this.jwplayer.getQualityLevels(), (item) => item.label.replace('p', ''))
for (const height of heights) {
const tooBig = height > newHeight
if (tooBig) {
break
}
optimalQuality = height + 'p'
}
if (optimalQuality !== this.jwplayer.getQualityLevels()[this.jwplayer.getCurrentQuality()].label) {
// tslint:disable-next-line:no-console
console.log('Switching quality to '
+ optimalQuality + ' because window will fit up to '
+ $(window).height() + 'p')
// find desired quality level and use it
const levels = this.jwplayer.getQualityLevels()
for (let j = 0; j < levels.length; j++) {
if (levels[j].label === optimalQuality) {
this.jwplayer.setCurrentQuality(j)
}
}
}
}
// preserve playback position
private onQualityChange() {
this.positionBeforeQualityChange = this.jwplayer.getPosition()
setTimeout(() => {
controls.seek(this.positionBeforeQualityChange)
}, 500)
}
}