2017-11-21 24 views
0

인터넷 속도에 따라 비트 레이트를 변경하는 방법이 코드 사용이 가능 :. jwplayer()를 getQualityLevels()JW 플레이어

답변

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) 
    } 

}