From f34077cd4e6b76353ccee3db470f900827ebbfc9 Mon Sep 17 00:00:00 2001 From: Tianxiao Wang Date: Thu, 11 Apr 2019 17:43:57 +0800 Subject: [PATCH] feat: adjust video quality (#65) * feat: adjust video quality --- packages/griffith-hls/src/index.js | 2 +- packages/griffith-mp4/src/index.js | 1 + packages/griffith-mp4/src/mse/controller.js | 42 ++++++++++++++++++--- packages/griffith-mp4/src/player.js | 2 +- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/packages/griffith-hls/src/index.js b/packages/griffith-hls/src/index.js index 7df96f40..ebf88260 100644 --- a/packages/griffith-hls/src/index.js +++ b/packages/griffith-hls/src/index.js @@ -1,7 +1,7 @@ import VideoComponent from './Video' export default { - pluginName: 'griffith-mp4', + pluginName: 'griffith-hls', VideoComponent, willHandleSrcChange: true, } diff --git a/packages/griffith-mp4/src/index.js b/packages/griffith-mp4/src/index.js index c5761d6a..df710414 100644 --- a/packages/griffith-mp4/src/index.js +++ b/packages/griffith-mp4/src/index.js @@ -3,4 +3,5 @@ import VideoComponent from './player' export default { pluginName: 'griffith-mp4', VideoComponent, + willHandleSrcChange: true, } diff --git a/packages/griffith-mp4/src/mse/controller.js b/packages/griffith-mp4/src/mse/controller.js index 5ca0eb35..5d76824e 100644 --- a/packages/griffith-mp4/src/mse/controller.js +++ b/packages/griffith-mp4/src/mse/controller.js @@ -10,6 +10,7 @@ export default class MSE { constructor(video, src) { this.video = video this.src = src + this.qualityChangeFlag = false this.videoQueue = [] this.audioQueue = [] this.sourceBuffers = { @@ -67,7 +68,7 @@ export default class MSE { init() { // 获取 mdat 外的数据 - this.loadData() + return this.loadData() .then(res => { return new MP4Parse(new Uint8Array(res)).mp4BoxTreeObject }) @@ -116,10 +117,17 @@ export default class MSE { FMP4.moov(this.mp4Probe.mp4Data, 'audio') ) - this.mediaSource.addEventListener('sourceopen', () => { + // 如果是切换清晰度,mediaSource 的 readyState 已经 open 了,可以直接 append 数据。 + // mediaSource is already open when we switch video quality. + if (this.qualityChangeFlag) { this.handleAppendBuffer(videoRawData, 'video') this.handleAppendBuffer(audioRawData, 'audio') - }) + } else { + this.mediaSource.addEventListener('sourceopen', () => { + this.handleAppendBuffer(videoRawData, 'video') + this.handleAppendBuffer(audioRawData, 'audio') + }) + } }) } @@ -144,10 +152,13 @@ export default class MSE { // 对于已经请求的数据不再重复请求 // No need to repeat request video data - if (time && this.hasBufferedCache(this.video.currentTime)) { + if ( + time && + this.hasBufferedCache(this.video.currentTime) && + !this.qualityChangeFlag + ) { return } - this.handleReplayCase() this.loadData(start, end).then(mdatBuffer => { @@ -180,9 +191,30 @@ export default class MSE { if (time) { this.needUpdateTime = true } + + this.qualityChangeFlag = false }) } + changeQuality(newSrc) { + this.src = newSrc + this.qualityChangeFlag = true + this.removeBuffer() + + this.init().then(() => { + this.video.currentTime = this.video.currentTime + }) + } + + removeBuffer() { + for (const key in this.sourceBuffers) { + const track = this.sourceBuffers[key] + const length = track.buffered.length + + track.remove(track.buffered.start(0), track.buffered.end(length - 1)) + } + } + loadData(start = 0, end = MAGIC_NUMBER) { return new Promise(resolve => { new FragmentFetch(this.src, start, end, resolve) diff --git a/packages/griffith-mp4/src/player.js b/packages/griffith-mp4/src/player.js index c9f239b0..5b02bdd6 100644 --- a/packages/griffith-mp4/src/player.js +++ b/packages/griffith-mp4/src/player.js @@ -12,7 +12,7 @@ export default class Player extends Component { componentDidUpdate(prevProps) { if (this.props.src !== prevProps.src) { - this.mse = new MSE(this.video, this.props.src) + this.mse.changeQuality(this.props.src) } }