Skip to content

Commit

Permalink
feat: add Controller & ProgressDot event (#177)
Browse files Browse the repository at this point in the history
Co-authored-by: zhangyue04 <zhangyue04@zhihu.com>
  • Loading branch information
TaraLoveCats and zhangyue04 authored Jun 24, 2021
1 parent 9f2ef89 commit 842c7b2
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 69 deletions.
9 changes: 9 additions & 0 deletions example/src/IframePage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ export default function IframePage() {
})
})

document
.getElementById('jsShowControllerFirst')
.addEventListener('click', () => {
dispatchMessage(firstVideoWindow, ACTIONS.PLAYER.SHOW_CONTROLLER)
})

return () => {
disposer.unsubscribe()
}
Expand All @@ -42,6 +48,7 @@ export default function IframePage() {
<p>场景 1:向一个视频发出暂停指令</p>
<p>场景 2:一个视频开始播放时,暂停其他视频</p>
<p>场景 3:手动 seek</p>
<p>场景 4:显示进度条</p>
<div>
<iframe src="/mp4?nonav" allowFullScreen frameBorder="0" />
<iframe src="/mp4?nonav" allowFullScreen frameBorder="0" />
Expand All @@ -54,6 +61,8 @@ export default function IframePage() {
<input id="time" />
<button id="jsSeekFirst">手动 seek 第一个视频</button>
</div>
<br />
<button id="jsShowControllerFirst">让第一个视频显示进度条</button>
</>
)
}
55 changes: 30 additions & 25 deletions packages/griffith-message/README-zh-Hans.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,27 @@ dispatchMessage(targetWindow, messageName, data)

从播放器接收到的事件

| `messageName` | 说明 | `data` |
| -------------------------------- | ---------------------- | ---------------------------------------- |
| `EVENTS.DOM.PLAY` | 播放 | 见下表 |
| `EVENTS.DOM.PLAYING` | 从暂停或缓冲中恢复播放 | 见下表 |
| `EVENTS.DOM.PAUSE` | 暂停 | 见下表 |
| `EVENTS.DOM.ENDED` | 停止 | 见下表 |
| `EVENTS.DOM.TIMEUPDATE` | 进度更新 | 见下表 |
| `EVENTS.DOM.ERROR` | 错误 | 见下表 |
| `EVENTS.DOM.WAITING` | 缓冲 | 见下表 |
| `EVENTS.PLAYER.REQUEST_PLAY` | 用户触发播放 ||
| `EVENTS.PLAYER.QUALITY_CHANGE` | 清晰度切换 | `{quality: string, prevQuality: string}` |
| `EVENTS.PLAYER.PLAY_COUNT` | 播放一次 ||
| `EVENTS.PLAYER.PLAY_FAILED` | 播放失败 | `{currentTime: number}` |
| `EVENTS.PLAYER.ENTER_FULLSCREEN` | 进入全屏 ||
| `EVENTS.PLAYER.EXIT_FULLSCREEN` | 退出全屏 ||
| `EVENTS.PLAYER.ENTER_PIP` | 进入画中画 ||
| `EVENTS.PLAYER.EXIT_PIP` | 退出画中画 ||
| `messageName` | 说明 | `data` |
| ---------------------------------- | ---------------------- | ------------------------------------------------ |
| `EVENTS.DOM.PLAY` | 播放 | 见下表 |
| `EVENTS.DOM.PLAYING` | 从暂停或缓冲中恢复播放 | 见下表 |
| `EVENTS.DOM.PAUSE` | 暂停 | 见下表 |
| `EVENTS.DOM.ENDED` | 停止 | 见下表 |
| `EVENTS.DOM.TIMEUPDATE` | 进度更新 | 见下表 |
| `EVENTS.DOM.ERROR` | 错误 | 见下表 |
| `EVENTS.DOM.WAITING` | 缓冲 | 见下表 |
| `EVENTS.PLAYER.REQUEST_PLAY` | 用户触发播放 ||
| `EVENTS.PLAYER.QUALITY_CHANGE` | 清晰度切换 | `{quality: string, prevQuality: string}` |
| `EVENTS.PLAYER.PLAY_COUNT` | 播放一次 ||
| `EVENTS.PLAYER.PLAY_FAILED` | 播放失败 | `{currentTime: number}` |
| `EVENTS.PLAYER.ENTER_FULLSCREEN` | 进入全屏 ||
| `EVENTS.PLAYER.EXIT_FULLSCREEN` | 退出全屏 ||
| `EVENTS.PLAYER.ENTER_PIP` | 进入画中画 ||
| `EVENTS.PLAYER.EXIT_PIP` | 退出画中画 ||
| `EVENTS.PLAYER.SHOW_CONTROLLER` | 显示播放器进度条控件 ||
| `EVENTS.PLAYER.HIDE_CONTROLLER` | 隐藏播放器进度条控件 ||
| `EVENTS.PLAYER.HOVER_PROGRESS_DOT` | 鼠标 hover 播放节点 | `{startTime: number, left: number, top: number}` |
| `EVENTS.PLAYER.LEAVE_PROGRESS_DOT` | 鼠标离开播放节点 ||

#### DOM 类 data

Expand All @@ -94,11 +98,12 @@ dispatchMessage(targetWindow, messageName, data)

往播放器发送的事件

| `messageName` | 说明 | `data` | 状态 |
| --------------------------------- | ---------------- | ------------------------------------------------- | ------ |
| `ACTIONS.PLAYER.PLAY` | 播放 | `{applyOnFullScreen: boolean}` 是否应用于全屏视频 | TODO |
| `ACTIONS.PLAYER.PAUSE` | 暂停 | 同上 | 已支持 |
| `ACTIONS.PLAYER.SET_VOLUME` | 设置音量 | `{volume: number}` 音量值,0 到 1 | TODO |
| `ACTIONS.PLAYER.ENTER_FULLSCREEN` | 进入全屏 || TODO |
| `ACTIONS.PLAYER.EXIT_FULLSCREEN` | 退出全屏 || TODO |
| `ACTIONS.PLAYER.TIME_UPDATE` | 设置视频播放进度 | `{currentTime: number} 设置视频当前的进度` | 已支持 |
| `messageName` | 说明 | `data` | 状态 |
| --------------------------------- | -------------------- | ------------------------------------------------- | ------ |
| `ACTIONS.PLAYER.PLAY` | 播放 | `{applyOnFullScreen: boolean}` 是否应用于全屏视频 | TODO |
| `ACTIONS.PLAYER.PAUSE` | 暂停 | 同上 | 已支持 |
| `ACTIONS.PLAYER.SET_VOLUME` | 设置音量 | `{volume: number}` 音量值,0 到 1 | TODO |
| `ACTIONS.PLAYER.ENTER_FULLSCREEN` | 进入全屏 || 已支持 |
| `ACTIONS.PLAYER.EXIT_FULLSCREEN` | 退出全屏 || 已支持 |
| `ACTIONS.PLAYER.TIME_UPDATE` | 设置视频播放进度 | `{currentTime: number} 设置视频当前的进度` | 已支持 |
| `ACTIONS.PLAYER.SHOW_CONTROLLER` | 显示播放器进度条控件 || 已支持 |
45 changes: 25 additions & 20 deletions packages/griffith-message/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,27 @@ dispatchMessage(targetWindow, messageName, data)

Events received from the player

| `messageName` | Description | `data` |
| -------------------------------- | ------------------------------------ | ---------------------------------------- |
| `EVENTS.DOM.PLAY` | Play | see DOM type data table |
| `EVENTS.DOM.PLAYING` | Resume playback from pause or buffer | see DOM type data table |
| `EVENTS.DOM.PAUSE` | Pause | see DOM type data table |
| `EVENTS.DOM.ENDED` | Ended | see DOM type data table |
| `EVENTS.DOM.TIMEUPDATE` | Timeupdate | see DOM type data table |
| `EVENTS.DOM.ERROR` | Error | see DOM type data table |
| `EVENTS.DOM.WAITING` | Buffer | see DOM type data table |
| `EVENTS.PLAYER.REQUEST_PLAY` | User starts playback | null |
| `EVENTS.PLAYER.QUALITY_CHANGE` | Play quality switching | `{quality: string, prevQuality: string}` |
| `EVENTS.PLAYER.PLAY_COUNT` | Playback | null |
| `EVENTS.PLAYER.PLAY_FAILED` | Play failed | `{currentTime: number}` |
| `EVENTS.PLAYER.ENTER_FULLSCREEN` | Enter Fullscreen | null |
| `EVENTS.PLAYER.EXIT_FULLSCREEN` | Exit Fullscreen | null |
| `EVENTS.PLAYER.ENTER_PIP` | Enter Picture in Picture | null |
| `EVENTS.PLAYER.EXIT_PIP` | Exit Picture in Picture | null |
| `messageName` | Description | `data` |
| ---------------------------------- | ------------------------------------ | ------------------------------------------------ |
| `EVENTS.DOM.PLAY` | Play | see DOM type data table |
| `EVENTS.DOM.PLAYING` | Resume playback from pause or buffer | see DOM type data table |
| `EVENTS.DOM.PAUSE` | Pause | see DOM type data table |
| `EVENTS.DOM.ENDED` | Ended | see DOM type data table |
| `EVENTS.DOM.TIMEUPDATE` | Timeupdate | see DOM type data table |
| `EVENTS.DOM.ERROR` | Error | see DOM type data table |
| `EVENTS.DOM.WAITING` | Buffer | see DOM type data table |
| `EVENTS.PLAYER.REQUEST_PLAY` | User starts playback | null |
| `EVENTS.PLAYER.QUALITY_CHANGE` | Play quality switching | `{quality: string, prevQuality: string}` |
| `EVENTS.PLAYER.PLAY_COUNT` | Playback | null |
| `EVENTS.PLAYER.PLAY_FAILED` | Play failed | `{currentTime: number}` |
| `EVENTS.PLAYER.ENTER_FULLSCREEN` | Enter Fullscreen | null |
| `EVENTS.PLAYER.EXIT_FULLSCREEN` | Exit Fullscreen | null |
| `EVENTS.PLAYER.ENTER_PIP` | Enter Picture in Picture | null |
| `EVENTS.PLAYER.EXIT_PIP` | Exit Picture in Picture | null |
| `EVENTS.PLAYER.SHOW_CONTROLLER` | Show Controller | null |
| `EVENTS.PLAYER.HIDE_CONTROLLER` | Hide Controller | null |
| `EVENTS.PLAYER.HOVER_PROGRESS_DOT` | Mouse hover progress dot | `{startTime: number, left: number, top: number}` |
| `EVENTS.PLAYER.LEAVE_PROGRESS_DOT` | Mouse leave progress dot | null |

#### DOM type data

Expand All @@ -99,6 +103,7 @@ Event sent to the player
| `ACTIONS.PLAYER.PLAY` | Play | `{applyOnFullScreen: boolean}` Applied to full screen video | TODO |
| `ACTIONS.PLAYER.PAUSE` | Pause | Applied to full screen video | SUPPORTED |
| `ACTIONS.PLAYER.SET_VOLUME` | Set the volume | `{volume: number}` Volume value from 0 to 1 | TODO |
| `ACTIONS.PLAYER.ENTER_FULLSCREEN` | Enter fullScreen | null | TODO |
| `ACTIONS.PLAYER.EXIT_FULLSCREEN` | Exit fullscreen | null | TODO |
| `ACTIONS.PLAYER.TIME_UPDATE` | 设置视频播放进度 | `{currentTime: number} Set the currentTime` | SUPPORTED |
| `ACTIONS.PLAYER.ENTER_FULLSCREEN` | Enter fullScreen | null | SUPPORTED |
| `ACTIONS.PLAYER.EXIT_FULLSCREEN` | Exit fullscreen | null | SUPPORTED |
| `ACTIONS.PLAYER.TIME_UPDATE` | Set current time | `{currentTime: number} Set the currentTime` | SUPPORTED |
| `ACTIONS.PLAYER.SHOW_CONTROLLER` | Show Controller | null | SUPPORTED |
5 changes: 5 additions & 0 deletions packages/griffith-message/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare const ACTIONS: {
EXIT_FULLSCREEN: string
ENTER_PIP: string
EXIT_PIP: string
SHOW_CONTROLLER: string
}
}

Expand All @@ -31,6 +32,10 @@ declare const EVENTS: {
EXIT_FULLSCREEN: string
ENTER_PIP: string
EXIT_PIP: string
SHOW_CONTROLLER: string
HIDE_CONTROLLER: string
HOVER_PROGRESS_DOT: string
LEAVE_PROGRESS_DOT: string
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/griffith-message/src/constants/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export const PLAYER = {
ENTER_PIP: 'action/player/enter-pip',
EXIT_PIP: 'action/player/exit-pip',
TIME_UPDATE: 'action/player/time-update',
SHOW_CONTROLLER: 'action/player/show-controller',
}
4 changes: 4 additions & 0 deletions packages/griffith-message/src/constants/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ export const PLAYER = {
EXIT_FULLSCREEN: 'event/player/exit-fullscreen',
ENTER_PIP: 'event/player/enter-pip',
EXIT_PIP: 'event/player/exit-pip',
SHOW_CONTROLLER: 'event/player/show-controller',
HIDE_CONTROLLER: 'event/player/hide-controller',
HOVER_PROGRESS_DOT: 'event/player/hover-progress-dot',
LEAVE_PROGRESS_DOT: 'event/player/leave-progress-dot',
}
6 changes: 6 additions & 0 deletions packages/griffith/src/components/Controller/Controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class Controller extends Component {
onQualityChange: PropTypes.func,
onVolumeChange: PropTypes.func,
onToggleFullScreen: PropTypes.func,
onProgressDotHover: PropTypes.func,
onProgressDotLeave: PropTypes.func,
show: PropTypes.bool,
showPip: PropTypes.bool,
progressDots: PropTypes.arrayOf(
Expand Down Expand Up @@ -287,6 +289,8 @@ class Controller extends Component {
hiddenQualityMenu,
hiddenVolumeItem,
hiddenFullScreenButton,
onProgressDotHover,
onProgressDotLeave,
} = this.props
const {
isVolumeHovered,
Expand Down Expand Up @@ -315,6 +319,8 @@ class Controller extends Component {
onDragEnd={onDragEnd}
onChange={this.onDragMove}
onSeek={this.handleSeek}
onProgressDotHover={onProgressDotHover}
onProgressDotLeave={onProgressDotLeave}
/>
)}
{hiddenTimeline && <div className={css(styles.timelineHolder)} />}
Expand Down
72 changes: 55 additions & 17 deletions packages/griffith/src/components/Player/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ class Player extends Component {
this.setDocumentTitle()
this.initPip()

if (this.getShowController(this.state)) {
this.props.onEvent(EVENTS.PLAYER.SHOW_CONTROLLER)
}

const historyVolume = storage.get('@griffith/history-volume')
if (historyVolume) {
this.setState({volume: historyVolume})
Expand All @@ -112,6 +116,11 @@ class Player extends Component {
({currentTime}) => this.handleSeek(currentTime)
)

this.showControllerActionSubscription = this.props.subscribeAction(
ACTIONS.PLAYER.SHOW_CONTROLLER,
this.handleShowController
)

if (this.videoRef.current.root) {
if (this.props.muted) {
this.handleVideoVolumeChange(0)
Expand All @@ -122,9 +131,41 @@ class Player extends Component {
}
}

componentDidUpdate() {
componentDidUpdate(preProps, preState) {
this.setDocumentTitle()
this.initPip()

const preShowController = this.getShowController(preState)
const showController = this.getShowController(this.state)

if (preShowController !== showController) {
if (showController) {
this.props.onEvent(EVENTS.PLAYER.SHOW_CONTROLLER)
} else {
this.props.onEvent(EVENTS.PLAYER.HIDE_CONTROLLER)
}
}
}

getShowController = ({
isPlaybackStarted,
isPlaying,
isControllerShown,
isControllerHovered,
isControllerDragging,
currentTime,
}) => {
// 播放中:暂停 或 Controller shown/hovered/dragging 时展示 Controller
if (isPlaybackStarted) {
return (
!isPlaying ||
isControllerShown ||
isControllerHovered ||
isControllerDragging
)
}
// 非播放中:播放结束时展示 Controller(未播放时不展示)
return currentTime !== 0
}

setDocumentTitle = () => {
Expand All @@ -151,6 +192,8 @@ class Player extends Component {

componentWillUnmount() {
this.pauseActionSubscription.unsubscribe()
this.timeUpdateActionSubscription.unsubscribe()
this.showControllerActionSubscription.unsubscribe()
}

handlePauseAction = ({dontApplyOnFullScreen} = {}) => {
Expand Down Expand Up @@ -384,6 +427,14 @@ class Player extends Component {
this.handleShowController()
}

handleProgressDotHover = info => {
this.props.onEvent(EVENTS.PLAYER.HOVER_PROGRESS_DOT, info)
}

handleProgressDotLeave = () => {
this.props.onEvent(EVENTS.PLAYER.LEAVE_PROGRESS_DOT)
}

render() {
const {
error,
Expand All @@ -409,9 +460,6 @@ class Player extends Component {
isPlaying,
isLoading,
duration,
isControllerShown,
isControllerHovered,
isControllerDragging,
currentTime,
isNeverPlayed,
volume,
Expand All @@ -424,19 +472,7 @@ class Player extends Component {
const isPip = Boolean(Pip.pictureInPictureElement)
// Safari 会将 pip 状态视为全屏
const isFullScreen = Boolean(BigScreen.element) && !isPip

// 未播放时不展示 Controller
// 播放中暂停时展示 Controller
// 播放中 Controller shown/hovered/dragging 时展示 Controller
// 播放结束展示 Controller
const showController =
(isPlaybackStarted &&
(!isPlaying ||
isControllerShown ||
isControllerHovered ||
isControllerDragging)) ||
(!isPlaybackStarted && currentTime !== 0)

const showController = this.getShowController(this.state)
const bufferedTime = getBufferedTime(currentTime, buffered)

return (
Expand Down Expand Up @@ -614,6 +650,8 @@ class Player extends Component {
onVolumeChange={this.handleVideoVolumeChange}
onToggleFullScreen={this.handleToggleFullScreen}
onTogglePip={this.handleTogglePip}
onProgressDotHover={this.handleProgressDotHover}
onProgressDotLeave={this.handleProgressDotLeave}
show={showController}
showPip={Pip.supported && !disablePictureInPicture}
hiddenPlayButton={hiddenPlayButton}
Expand Down
Loading

0 comments on commit 842c7b2

Please sign in to comment.