Skip to content

Commit

Permalink
refactor: distinguish native/custom event props in Video (zhihu#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
ambar authored Jan 24, 2022
1 parent 5cd3e33 commit 1fe1fb7
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 44 deletions.
18 changes: 12 additions & 6 deletions packages/griffith/src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import {css} from 'aphrodite/no-important'
import BigScreen from 'isomorphic-bigscreen'
import {EVENTS, ACTIONS} from 'griffith-message'
import {ua} from 'griffith-utils'
import {ProgressDot, PlaybackRate, PlaySourceMap, RealQuality} from '../types'
import {
ProgressDot,
ProgressValue,
PlaybackRate,
PlaySourceMap,
RealQuality,
} from '../types'
import {
defaultLocale,
LocaleCode,
Expand Down Expand Up @@ -111,7 +117,7 @@ type State = {
duration: number
currentTime: number
volume: number
buffered: {start: number; end: number}[][]
buffered: ProgressValue[]
isControllerShown: boolean
isControllerHovered: boolean
isControllerDragging: boolean
Expand Down Expand Up @@ -418,7 +424,7 @@ class InnerPlayer extends Component<InnerPlayerProps, State> {
this.isSeeking = false
}

handleVideoProgress = (buffered: any) => {
handleVideoProgress = (buffered: ProgressValue[]) => {
this.setState({buffered})
}

Expand Down Expand Up @@ -607,12 +613,12 @@ class InnerPlayer extends Component<InnerPlayerProps, State> {
onEnded={this.handleVideoEnded}
onLoadedData={this.handleVideoLoadedData}
onError={this.handleVideoError}
onDurationChange={this.handleVideoDurationChange}
onTimeUpdate={this.handleVideoTimeUpdate}
onLoadingChange={this.handleLoadingChange}
onDurationUpdate={this.handleVideoDurationChange}
onCurrentTimeUpdate={this.handleVideoTimeUpdate}
onSeeking={this.handleVideoSeeking}
onSeeked={this.handleVideoSeeked}
onProgress={this.handleVideoProgress}
onProgressUpdate={this.handleVideoProgress}
onEvent={onEvent}
useMSE={useMSE}
useAutoQuality={useAutoQuality}
Expand Down
69 changes: 31 additions & 38 deletions packages/griffith/src/components/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, {Component} from 'react'
import {css} from 'aphrodite/no-important'
import {EVENTS} from 'griffith-message'
import {logger, ua} from 'griffith-utils'
import {PlaybackRate, Quality, PlaySource} from '../types'
import {PlaybackRate, Quality, PlaySource, ProgressValue} from '../types'
import VideoSourceContext from '../contexts/VideoSourceContext'
import VideoWithMessage, {VideoComponentType} from './VideoWithMessage'
import selectVideo from './selectVideo'
Expand All @@ -17,31 +17,20 @@ const isAbortError = (error: MediaError) =>
const isNotAllowedError = (error: MediaError) =>
error && (error as unknown as Error).name === 'NotAllowedError'

type ProgressValue = {
start: number
end: number
}
type NativeVideoProps = Omit<React.HTMLProps<HTMLVideoElement>, 'ref'>

type VideoProps = {
src: string
type VideoProps = NativeVideoProps & {
format: string
controls?: boolean
loop?: boolean
paused?: boolean
useMSE?: boolean
volume: number
currentQuality?: Quality
sources?: PlaySource[]
// 自定义事件(注意与原生不同,附加了自定义参数)
onLoadingChange?: (isLoading: boolean) => void
onPlay?: (...args: any[]) => any
onPause?: (...args: any[]) => any
onEnded?: (...args: any[]) => any
onLoadedData?: (...args: any[]) => any
onDurationChange?: (...args: any[]) => any
onTimeUpdate?: (...args: any[]) => any
onSeeking?: (...args: any[]) => any
onSeeked?: (...args: any[]) => any
onProgress?: (values: ProgressValue[]) => any
onDurationUpdate: (duration: number) => void
onProgressUpdate: (value: ProgressValue[]) => void
onCurrentTimeUpdate: (time: number, isRaf: boolean) => void
onError: (...args: any[]) => any
onEvent: (name: EVENTS, data?: unknown) => void
currentPlaybackRate: PlaybackRate
Expand All @@ -54,7 +43,7 @@ class Video extends Component<VideoProps> {
volume: 0.5,
}

_playTimer: any
_timeUpdateRafId?: number
handleClick: any
playPromise?: Promise<void>

Expand Down Expand Up @@ -240,9 +229,9 @@ class Video extends Component<VideoProps> {
}

handleDurationChange = () => {
const {onDurationChange} = this.props
if (onDurationChange) {
onDurationChange(this.root!.duration)
const {onDurationUpdate} = this.props
if (onDurationUpdate) {
onDurationUpdate(this.root!.duration)
}
}

Expand Down Expand Up @@ -271,27 +260,35 @@ class Video extends Component<VideoProps> {
}
}

handleTimeUpdate = (arg: any) => {
const {onTimeUpdate, paused} = this.props
handleTimeUpdate = () => {
this.notifyTimeUpdate(false)
}

// NOTE: 原生 `timeupdate` 事件更新频率不固定(4Hz~66Hz,由系统决定),这里以 rAF 提高了 UI 更新频率
// 但进度条更新仍然是不平滑的,需要考虑使用进度动画(TODO)
notifyTimeUpdate = (isRaf: boolean) => {
const {onCurrentTimeUpdate, paused} = this.props

this.disposeTimer()
if (this._timeUpdateRafId !== undefined) {
window.cancelAnimationFrame(this._timeUpdateRafId)
}
if (paused || this.loading) {
return
}
const {currentTime} = this.root || {}

if (onTimeUpdate && currentTime) {
const isRaf = typeof arg === 'number' // raf 调用 arg 是 时间戳,事件监听调用 arg 是 event
onTimeUpdate(currentTime, isRaf)
const currentTime = this.root?.currentTime
if (onCurrentTimeUpdate && currentTime) {
onCurrentTimeUpdate(currentTime, isRaf)
if (!isMobile) {
// 移动端使用原生进度条,不需要频繁更新,减少性能压力
this._playTimer = window.requestAnimationFrame(this.handleTimeUpdate)
this._timeUpdateRafId = window.requestAnimationFrame(() =>
this.notifyTimeUpdate(true)
)
}
}
}

handleProgress = () => {
const {onProgress} = this.props
const {onProgressUpdate} = this.props
const buffered = this.root!.buffered
const result: ProgressValue[] = []
for (let i = 0; i < buffered.length; i++) {
Expand All @@ -300,15 +297,11 @@ class Video extends Component<VideoProps> {
end: buffered.end(i),
})
}
if (onProgress) {
onProgress(result)
if (onProgressUpdate) {
onProgressUpdate(result)
}
}

disposeTimer() {
window.cancelAnimationFrame(this._playTimer)
}

handleError = () => {
const {error, currentTime} = this.root || {}
if (!error) {
Expand Down
5 changes: 5 additions & 0 deletions packages/griffith/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ export interface PlaybackRate {
export type ProgressDot = {
startTime: number
}

export type ProgressValue = {
start: number
end: number
}

0 comments on commit 1fe1fb7

Please sign in to comment.