fullscreen API
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, {useEffect, useRef, useState} from 'react'
|
import React, {useCallback, useEffect, useRef, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
|
import Animated, {FadeIn, FadeOut} from 'react-native-reanimated'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
@@ -86,6 +86,7 @@ export function VideoPlayer({
|
|||||||
onScreen: boolean
|
onScreen: boolean
|
||||||
}) {
|
}) {
|
||||||
const [hls] = useState(() => new Hls())
|
const [hls] = useState(() => new Hls())
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
const ref = useRef<HTMLVideoElement>(null)
|
const ref = useRef<HTMLVideoElement>(null)
|
||||||
const [focused, setFocused] = useState(false)
|
const [focused, setFocused] = useState(false)
|
||||||
|
|
||||||
@@ -115,6 +116,12 @@ export function VideoPlayer({
|
|||||||
}
|
}
|
||||||
}, [source, hls])
|
}, [source, hls])
|
||||||
|
|
||||||
|
const enterFullscreen = useCallback(() => {
|
||||||
|
if (containerRef.current) {
|
||||||
|
containerRef.current.requestFullscreen()
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
@@ -136,6 +143,7 @@ export function VideoPlayer({
|
|||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<div ref={containerRef} style={{flex: 1}}>
|
||||||
<Controls
|
<Controls
|
||||||
videoRef={ref}
|
videoRef={ref}
|
||||||
active={active}
|
active={active}
|
||||||
@@ -143,6 +151,7 @@ export function VideoPlayer({
|
|||||||
focused={focused}
|
focused={focused}
|
||||||
setFocused={setFocused}
|
setFocused={setFocused}
|
||||||
onScreen={onScreen}
|
onScreen={onScreen}
|
||||||
|
enterFullscreen={enterFullscreen}
|
||||||
/>
|
/>
|
||||||
<video
|
<video
|
||||||
src={source}
|
src={source}
|
||||||
@@ -153,6 +162,7 @@ export function VideoPlayer({
|
|||||||
loop
|
loop
|
||||||
muted={!focused}
|
muted={!focused}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -164,6 +174,7 @@ function Controls({
|
|||||||
focused,
|
focused,
|
||||||
setFocused,
|
setFocused,
|
||||||
onScreen,
|
onScreen,
|
||||||
|
enterFullscreen,
|
||||||
}: {
|
}: {
|
||||||
videoRef: React.RefObject<HTMLVideoElement>
|
videoRef: React.RefObject<HTMLVideoElement>
|
||||||
active: boolean
|
active: boolean
|
||||||
@@ -171,6 +182,7 @@ function Controls({
|
|||||||
focused: boolean
|
focused: boolean
|
||||||
setFocused: (focused: boolean) => void
|
setFocused: (focused: boolean) => void
|
||||||
onScreen: boolean
|
onScreen: boolean
|
||||||
|
enterFullscreen: () => void
|
||||||
}) {
|
}) {
|
||||||
const {play, pause, playing, muted, togglePlayPause, currentTime, duration} =
|
const {play, pause, playing, muted, togglePlayPause, currentTime, duration} =
|
||||||
useVideoUtils(videoRef)
|
useVideoUtils(videoRef)
|
||||||
@@ -217,6 +229,7 @@ function Controls({
|
|||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={onMouseLeave}>
|
onMouseLeave={onMouseLeave}>
|
||||||
{hovered && (
|
{hovered && (
|
||||||
|
<>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
a.w_full,
|
a.w_full,
|
||||||
@@ -237,6 +250,7 @@ function Controls({
|
|||||||
size="medium">
|
size="medium">
|
||||||
<ButtonIcon icon={playing ? PauseIcon : PlayIcon} />
|
<ButtonIcon icon={playing ? PauseIcon : PlayIcon} />
|
||||||
</Button>
|
</Button>
|
||||||
|
<View style={a.flex_1} />
|
||||||
<Button
|
<Button
|
||||||
label={_(muted ? msg`Unmute` : msg`Mute`)}
|
label={_(muted ? msg`Unmute` : msg`Mute`)}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
@@ -247,12 +261,15 @@ function Controls({
|
|||||||
size="medium">
|
size="medium">
|
||||||
<ButtonIcon icon={muted ? MuteIcon : UnmuteIcon} />
|
<ButtonIcon icon={muted ? MuteIcon : UnmuteIcon} />
|
||||||
</Button>
|
</Button>
|
||||||
<View style={a.flex_1} />
|
|
||||||
{/* TODO: find workaround for iOS Safari */}
|
{/* TODO: find workaround for iOS Safari */}
|
||||||
<Button
|
<Button
|
||||||
label={_(muted ? msg`Unmute` : msg`Mute`)}
|
label={_(muted ? msg`Unmute` : msg`Mute`)}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
console.log('clicked fullscreen btn')
|
if (document.fullscreenElement) {
|
||||||
|
document.exitFullscreen()
|
||||||
|
} else {
|
||||||
|
enterFullscreen()
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
shape="round"
|
shape="round"
|
||||||
@@ -260,6 +277,7 @@ function Controls({
|
|||||||
<ButtonIcon icon={FullscreenIcon} />
|
<ButtonIcon icon={FullscreenIcon} />
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{(hovered || !focused) && (
|
{(hovered || !focused) && (
|
||||||
<Animated.View
|
<Animated.View
|
||||||
@@ -305,6 +323,13 @@ function useVideoUtils(ref: React.RefObject<HTMLVideoElement>) {
|
|||||||
if (!ref.current) return
|
if (!ref.current) return
|
||||||
let current = ref.current
|
let current = ref.current
|
||||||
|
|
||||||
|
// Initial values
|
||||||
|
setCurrentTime(current.currentTime || 0)
|
||||||
|
setDuration(current.duration || 0)
|
||||||
|
setCanPlay(current.readyState >= HTMLMediaElement.HAVE_FUTURE_DATA)
|
||||||
|
setMuted(current.muted)
|
||||||
|
setPlaying(!current.paused)
|
||||||
|
|
||||||
const handleTimeUpdate = () => {
|
const handleTimeUpdate = () => {
|
||||||
if (!current) return
|
if (!current) return
|
||||||
setCurrentTime(current.currentTime || 0)
|
setCurrentTime(current.currentTime || 0)
|
||||||
@@ -384,11 +409,7 @@ function useVideoUtils(ref: React.RefObject<HTMLVideoElement>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const togglePlayPause = () => {
|
const togglePlayPause = () => {
|
||||||
if (playing) {
|
setPlaying(p => !p)
|
||||||
play()
|
|
||||||
} else {
|
|
||||||
pause()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {play, pause, togglePlayPause, duration, currentTime, playing, muted}
|
return {play, pause, togglePlayPause, duration, currentTime, playing, muted}
|
||||||
|
|||||||
Reference in New Issue
Block a user