diff --git a/example/src/LayerTest.jsx b/example/src/LayerTest.jsx deleted file mode 100644 index 2cd886c4..00000000 --- a/example/src/LayerTest.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import React, {Component} from 'react' -import {StyleSheet, css} from 'aphrodite/no-important' -import {Layer} from 'griffith' -import {EVENTS} from 'griffith-message' - -const styles = StyleSheet.create({ - logo: { - width: '20%', - position: 'absolute', - top: '3%', - right: '4%', - }, -}) - -const LOGO_SRC = 'http://zhstatic.zhihu.com/assets/zhihu/web-logo@2x.png' - -class LayerTest extends Component { - state = { - shouldShow: false, - } - - componentDidMount() { - const usp = new URLSearchParams(location.search) - if (usp.has('logo')) { - this.subscription = this.props.subscribeEvent( - EVENTS.PLAYER.PLAY_COUNT, - () => { - this.setState({shouldShow: true}) - } - ) - } - } - - componentWillUnmount() { - if (this.subscription) { - this.subscription.unsubscribe() - } - } - - render() { - const {shouldShow} = this.state - - return ( - shouldShow && ( - - - - ) - ) - } -} - -export default LayerTest diff --git a/example/src/Logo.jsx b/example/src/Logo.jsx new file mode 100644 index 00000000..044c223b --- /dev/null +++ b/example/src/Logo.jsx @@ -0,0 +1,19 @@ +import React from 'react' +import {StyleSheet, css} from 'aphrodite/no-important' + +const styles = StyleSheet.create({ + logo: { + width: '20%', + position: 'absolute', + top: '3%', + right: '4%', + }, +}) + +const LOGO_SRC = 'http://zhstatic.zhihu.com/assets/zhihu/web-logo@2x.png' + +function Logo() { + return +} + +export default Logo diff --git a/example/src/MP4Page.jsx b/example/src/MP4Page.jsx index a93f93f9..48d26718 100644 --- a/example/src/MP4Page.jsx +++ b/example/src/MP4Page.jsx @@ -1,6 +1,6 @@ -import React from 'react' -import PlayerContainer, {MessageContext} from 'griffith' -import LayerTest from './LayerTest' +import React, {useState, useLayoutEffect, useContext} from 'react' +import PlayerContainer, {MessageContext, EVENTS} from 'griffith' +import Logo from './Logo' const duration = 182 @@ -35,13 +35,26 @@ const props = { autoplay: true, shouldObserveResize: true, src: 'https://zhstatic.zhihu.com/cfe/griffith/zhihu2018_sd.mp4', + // eslint-disable-next-line no-console + onEvent: console.log.bind(null, 'onEvent:'), +} + +const canShowLogo = new URLSearchParams(location.search).has('logo') +/** 常规通讯方式,建议直接使用 `onEvent` 替代 */ +const LogoListener = () => { + const [isLogoVisible, setIsLogoVisible] = useState(false) + const {subscribeEvent} = useContext(MessageContext) + useLayoutEffect(() => { + return subscribeEvent(EVENTS.PLAYER.PLAY_COUNT, () => { + setIsLogoVisible(true) + }).unsubscribe + }, []) + return canShowLogo && isLogoVisible ? : null } const App = () => ( - - {({subscribeEvent}) => } - + ) diff --git a/packages/griffith/README-zh-Hans.md b/packages/griffith/README-zh-Hans.md index 4b8ecabb..6b5ccb4c 100644 --- a/packages/griffith/README-zh-Hans.md +++ b/packages/griffith/README-zh-Hans.md @@ -28,6 +28,7 @@ render() | `useAutoQuality` | `boolean` | `false` | 是否启用自动清晰度功能 | | `standalone` | `boolean` | `false` | 是否启用 standalone 模式 | | `onBeforePlay` | `function` | `void` | 视频播放之前回调函数 | +| `onEvent` | `(type: string) => void` | `void` | 公共事件的回调函数 | | `shouldObserveResize` | `boolean` | `false` | 是否监听窗口 resize | | `initialObjectFit` | `fill \| \contain \| cover \| none \| scale-down` | `contain` | object-fit 参数 | | `useMSE` | `boolean` | `false` | 是否启用 MSE | diff --git a/packages/griffith/README.md b/packages/griffith/README.md index 25090426..9245f801 100644 --- a/packages/griffith/README.md +++ b/packages/griffith/README.md @@ -18,32 +18,32 @@ render() ### `Props` -| Name | Type | Default | Description | -| ------------------------- | ------------------------------------------------ | ---------------- | ------------------------------------------------------------------------ | -| `id` | `string` | | Unique identifier of the player instance | -| `title` | `string` | | Video title | -| `cover` | `string` | | Video cover image | -| `duration` | `number` | | Initial video duration. Use actual values after video metadata is loaded | -| `sources` | `sources` | | Video playback data | -| `defaultQuality` | `ld \| sd \| hd \| fhd` | | Video default quality | -| `useAutoQuality` | `boolean` | `false` | Enable auto quality | -| `standalone` | `boolean` | `false` | Enable standalone mode | -| `onBeforePlay` | `function` | `void` | Callback function before video playback | -| `onFullScreenChange` | `function` | `status => void` | Callback function when fullScreen status has changed | -| `shouldObserveResize` | `boolean` | `false` | Listen to the window resize | -| `initialObjectFit` | `fill \| contain \| cover \| none \| scale-down` | `contain` | object-fit | -| `useMSE` | `boolean` | `false` | Enable Media Source Extensions™ | -| `locale` | `en \| ja \| zh-Hans \| zh-Hant` | `en` | UI Locale | -| `autoplay` | `boolean` | `false` | Autoplay | -| `muted` | `boolean` | `false` | Muted | -| `disablePictureInPicture` | `boolean` | `false` | Disable Picture in Picture feature | -| `hiddenPlayButton` | `boolean` | `false` | Hide play button | -| `hiddenTimeline` | `boolean` | `false` | Hide progress bar | -| `hiddenTime` | `boolean` | `false` | Hide duration and total time | -| `hiddenQualityMenu` | `boolean` | `false` | Hide quality menu (if it is shown) | -| `hiddenVolume` | `boolean` | `false` | Hide volume | -| `hiddenFullScreenButton` | `boolean` | `false` | Hide full screen button | -| `progressDots` | `ProgressDotItem[]` | `[]` | Node information on the progress bar | +| Name | Type | Default | Description | +| ------------------------- | ------------------------------------------------ | --------- | ------------------------------------------------------------------------ | +| `id` | `string` | | Unique identifier of the player instance | +| `title` | `string` | | Video title | +| `cover` | `string` | | Video cover image | +| `duration` | `number` | | Initial video duration. Use actual values after video metadata is loaded | +| `sources` | `sources` | | Video playback data | +| `defaultQuality` | `ld \| sd \| hd \| fhd` | | Video default quality | +| `useAutoQuality` | `boolean` | `false` | Enable auto quality | +| `standalone` | `boolean` | `false` | Enable standalone mode | +| `onBeforePlay` | `function` | `void` | Callback function before video playback | +| `onEvent` | `(type: string) => void` | `void` | Callback function when common event is triggered | +| `shouldObserveResize` | `boolean` | `false` | Listen to the window resize | +| `initialObjectFit` | `fill \| contain \| cover \| none \| scale-down` | `contain` | object-fit | +| `useMSE` | `boolean` | `false` | Enable Media Source Extensions™ | +| `locale` | `en \| ja \| zh-Hans \| zh-Hant` | `en` | UI Locale | +| `autoplay` | `boolean` | `false` | Autoplay | +| `muted` | `boolean` | `false` | Muted | +| `disablePictureInPicture` | `boolean` | `false` | Disable Picture in Picture feature | +| `hiddenPlayButton` | `boolean` | `false` | Hide play button | +| `hiddenTimeline` | `boolean` | `false` | Hide progress bar | +| `hiddenTime` | `boolean` | `false` | Hide duration and total time | +| `hiddenQualityMenu` | `boolean` | `false` | Hide quality menu (if it is shown) | +| `hiddenVolume` | `boolean` | `false` | Hide volume | +| `hiddenFullScreenButton` | `boolean` | `false` | Hide full screen button | +| `progressDots` | `ProgressDotItem[]` | `[]` | Node information on the progress bar | `sources`: diff --git a/packages/griffith/index.d.ts b/packages/griffith/index.d.ts index 90780e66..dad16207 100644 --- a/packages/griffith/index.d.ts +++ b/packages/griffith/index.d.ts @@ -1,4 +1,5 @@ import React from 'react' +import {EVENTS} from 'griffith-message' type RealQuality = 'ld' | 'sd' | 'hd' | 'fhd' @@ -23,7 +24,7 @@ interface PlayerContainerProps { message: string } onBeforePlay?: (src: string) => Promise - onFullScreenChange?: (status: boolean) => void + onEvent?: (type: string) => void shouldObserveResize?: boolean initialObjectFit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' useMSE?: boolean @@ -73,4 +74,4 @@ declare const Layer: React.ComponentType export default PlayerContainer -export {VideoSourceContext, MessageContext, Layer} +export {VideoSourceContext, MessageContext, Layer, EVENTS} diff --git a/packages/griffith/src/components/Player/Player.js b/packages/griffith/src/components/Player/Player.js index 1ae7e182..93a0f7bf 100644 --- a/packages/griffith/src/components/Player/Player.js +++ b/packages/griffith/src/components/Player/Player.js @@ -38,7 +38,6 @@ class Player extends Component { ), onEvent: PropTypes.func.isRequired, onBeforePlay: PropTypes.func.isRequired, - onFullScreenChange: PropTypes.func.isRequired, autoplay: PropTypes.bool, muted: PropTypes.bool, disablePictureInPicture: PropTypes.bool, @@ -306,13 +305,11 @@ class Player extends Component { handleToggleFullScreen = () => { if (BigScreen.enabled) { - const {onEvent, onFullScreenChange} = this.props + const {onEvent} = this.props const onEnter = () => { - onFullScreenChange(true) return onEvent(EVENTS.PLAYER.ENTER_FULLSCREEN) } const onExit = () => { - onFullScreenChange(false) return onEvent(EVENTS.PLAYER.EXIT_FULLSCREEN) } BigScreen.toggle(this.playerRef.current, onEnter, onExit) diff --git a/packages/griffith/src/components/PlayerContainer/PlayerContainer.js b/packages/griffith/src/components/PlayerContainer/PlayerContainer.js index b40c759a..5bc4af33 100644 --- a/packages/griffith/src/components/PlayerContainer/PlayerContainer.js +++ b/packages/griffith/src/components/PlayerContainer/PlayerContainer.js @@ -1,6 +1,7 @@ import React from 'react' import PropTypes from 'prop-types' - +import noop from 'lodash/noop' +import {sequence} from 'griffith-utils' import Player from '../Player' import { VideoSourceProvider, @@ -20,7 +21,7 @@ const PlayerContainer = ({ sources, error, onBeforePlay = () => Promise.resolve(), - onFullScreenChange = () => {}, + onEvent, shouldObserveResize, children, initialObjectFit = 'contain', @@ -45,7 +46,7 @@ const PlayerContainer = ({ {({emitEvent, subscribeAction}) => ( onBeforePlay(currentSrc)} - onFullScreenChange={onFullScreenChange} /> )} @@ -110,7 +110,7 @@ PlayerContainer.propTypes = { message: PropTypes.string, }), onBeforePlay: PropTypes.func, - onFullScreenChange: PropTypes.func, + onEvent: PropTypes.func, initialObjectFit: PropTypes.oneOf(VALID_FIT), useMSE: PropTypes.bool, defaultQuality: PropTypes.oneOf(['ld', 'sd', 'hd', 'fhd']), diff --git a/packages/griffith/src/index.js b/packages/griffith/src/index.js index 8b2067b0..156abd4f 100644 --- a/packages/griffith/src/index.js +++ b/packages/griffith/src/index.js @@ -3,3 +3,4 @@ export {ExternalContext as MessageContext} from './contexts/Message' export {VideoSourceContext} from './contexts/VideoSource' export {default as Controller} from './components/Controller' export {default as Layer} from './components/Layer' +export {EVENTS} from 'griffith-message'