From 0261ddb54b53b781ff17d2033b3df25923fd5751 Mon Sep 17 00:00:00 2001 From: Tianxiao Wang Date: Thu, 18 Apr 2019 17:40:45 +0800 Subject: [PATCH] fix: don't use MSE If the video don't have a video track (#78) --- packages/griffith-mp4/src/mp4/mp4Probe.js | 38 +++++++++++++-------- packages/griffith-mp4/src/mse/controller.js | 4 ++- packages/griffith-mp4/src/player.js | 30 ++++++++++++---- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/packages/griffith-mp4/src/mp4/mp4Probe.js b/packages/griffith-mp4/src/mp4/mp4Probe.js index de6feb17..e3905008 100644 --- a/packages/griffith-mp4/src/mp4/mp4Probe.js +++ b/packages/griffith-mp4/src/mp4/mp4Probe.js @@ -114,18 +114,13 @@ export default class MP4Probe { getMP4Data() { const {duration, timescale} = findBox(this.mp4BoxTree, 'mvhd') - const {width, height} = findBox(this.mp4BoxTree, 'videoTkhd') - const {samples} = findBox(this.mp4BoxTree, 'videoStsz') - const {SPS, PPS} = findBox(this.mp4BoxTree, 'avcC') + const {channelCount, sampleRate} = findBox(this.mp4BoxTree, 'mp4a') const {timescale: audioTimescale, duration: audioDuration} = findBox( this.mp4BoxTree, 'audioMdhd' ) - const {timescale: videoTimescale, duration: videoDuration} = findBox( - this.mp4BoxTree, - 'videoMdhd' - ) + const { ESDescrTag: { DecSpecificDescrTag: {audioConfig}, @@ -135,18 +130,33 @@ export default class MP4Probe { this.mp4Data = { duration, timescale, - width, - height, - SPS, - PPS, channelCount, sampleRate, audioConfig, audioDuration, - videoDuration, audioTimescale, - videoTimescale, - videoSamplesLength: samples.length, + } + + const hasVideoStream = findBox(this.mp4BoxTree, 'videoTrak') + if (hasVideoStream) { + const {width, height} = findBox(this.mp4BoxTree, 'videoTkhd') + const {samples} = findBox(this.mp4BoxTree, 'videoStsz') + const {SPS, PPS} = findBox(this.mp4BoxTree, 'avcC') + const {timescale: videoTimescale, duration: videoDuration} = findBox( + this.mp4BoxTree, + 'videoMdhd' + ) + + this.mp4Data = { + ...this.mp4Data, + width, + height, + SPS, + PPS, + videoDuration, + videoTimescale, + videoSamplesLength: samples.length, + } } } } diff --git a/packages/griffith-mp4/src/mse/controller.js b/packages/griffith-mp4/src/mse/controller.js index 3bad649d..3d55abde 100644 --- a/packages/griffith-mp4/src/mse/controller.js +++ b/packages/griffith-mp4/src/mse/controller.js @@ -63,7 +63,9 @@ export default class MSE { handleAppendBuffer = (buffer, type) => { if (this.mediaSource.readyState === 'open') { try { - this.sourceBuffers[type].appendBuffer(buffer) + if (this.sourceBuffers[type]) { + this.sourceBuffers[type].appendBuffer(buffer) + } } catch (error) { // see https://developers.google.com/web/updates/2017/10/quotaexceedederror if (error.name === 'QuotaExceededError') { diff --git a/packages/griffith-mp4/src/player.js b/packages/griffith-mp4/src/player.js index c8e7f1f7..55b088eb 100644 --- a/packages/griffith-mp4/src/player.js +++ b/packages/griffith-mp4/src/player.js @@ -5,23 +5,35 @@ import MSE from './mse' const {isSafari} = ua export default class Player extends Component { + useMSE = true + componentDidMount() { this.mse = new MSE(this.video, this.props.src) - this.mse.init() + this.mse.init().then(() => { + // don't use MSE If the video don't have a video track + if (!this.mse.mp4Probe.mp4Data.videoDuration) { + this.useMSE = false + this.video.src = this.props.src + } + }) } componentDidUpdate(prevProps) { - if (this.props.src !== prevProps.src) { + if (this.props.src !== prevProps.src && this.useMSE) { this.mse.changeQuality(this.props.src) } } componentWillUnmount() { - this.mse.destroy() + if (this.useMSE) { + this.mse.destroy() + } } handleTimeUpdate = e => { - this.mse.handleTimeUpdate() + if (this.useMSE) { + this.mse.handleTimeUpdate() + } this.props.onTimeUpdate(e) } @@ -31,20 +43,24 @@ export default class Player extends Component { if (isSafari && buffered && buffered.length > 0) { if (currentTime - 0.1 > buffered.start(0)) { - this.mse.seek(this.video.currentTime) + if (this.useMSE) { + this.mse.seek(this.video.currentTime) + } } else if (currentTime < buffered.start(0)) { this.handleSafariBug() return } } else { - this.mse.seek(this.video.currentTime) + if (this.useMSE) { + this.mse.seek(this.video.currentTime) + } } this.props.onSeeking(e) } handlePlay = e => { const {currentTime} = this.video - if (currentTime === 0) { + if (currentTime === 0 && this.useMSE) { this.mse.seek(0) }