[Video] Disable autoplay option (preview + web player) (#5167)

* rename setting

* preview (web)

* preview (native)

* improve autoplay disabled behaviour on web
zio/stable
Samuel Newman 2024-09-05 15:56:10 +01:00 committed by GitHub
parent d846f5bbf0
commit 60b74f7ab8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 32 additions and 8 deletions

View File

@ -6,8 +6,10 @@ import {useVideoPlayer, VideoView} from 'expo-video'
import {CompressedVideo} from '#/lib/media/video/types' import {CompressedVideo} from '#/lib/media/video/types'
import {clamp} from '#/lib/numbers' import {clamp} from '#/lib/numbers'
import {useAutoplayDisabled} from '#/state/preferences'
import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn' import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
export function VideoPreview({ export function VideoPreview({
asset, asset,
@ -20,10 +22,13 @@ export function VideoPreview({
clear: () => void clear: () => void
}) { }) {
const t = useTheme() const t = useTheme()
const autoplayDisabled = useAutoplayDisabled()
const player = useVideoPlayer(video.uri, player => { const player = useVideoPlayer(video.uri, player => {
player.loop = true player.loop = true
player.muted = true player.muted = true
player.play() if (!autoplayDisabled) {
player.play()
}
}) })
let aspectRatio = asset.width / asset.height let aspectRatio = asset.width / asset.height
@ -53,6 +58,11 @@ export function VideoPreview({
contentFit="contain" contentFit="contain"
/> />
<ExternalEmbedRemoveBtn onRemove={clear} /> <ExternalEmbedRemoveBtn onRemove={clear} />
{autoplayDisabled && (
<View style={[a.absolute, a.inset_0, a.justify_center, a.align_center]}>
<PlayButtonIcon size={48} />
</View>
)}
</View> </View>
) )
} }

View File

@ -6,9 +6,11 @@ import {useLingui} from '@lingui/react'
import {CompressedVideo} from '#/lib/media/video/types' import {CompressedVideo} from '#/lib/media/video/types'
import {clamp} from '#/lib/numbers' import {clamp} from '#/lib/numbers'
import {useAutoplayDisabled} from '#/state/preferences'
import * as Toast from '#/view/com/util/Toast' import * as Toast from '#/view/com/util/Toast'
import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn' import {ExternalEmbedRemoveBtn} from 'view/com/composer/ExternalEmbedRemoveBtn'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
export function VideoPreview({ export function VideoPreview({
asset, asset,
@ -23,6 +25,7 @@ export function VideoPreview({
}) { }) {
const ref = useRef<HTMLVideoElement>(null) const ref = useRef<HTMLVideoElement>(null)
const {_} = useLingui() const {_} = useLingui()
const autoplayDisabled = useAutoplayDisabled()
useEffect(() => { useEffect(() => {
if (!ref.current) return if (!ref.current) return
@ -66,17 +69,23 @@ export function VideoPreview({
{aspectRatio}, {aspectRatio},
a.overflow_hidden, a.overflow_hidden,
{backgroundColor: 'black'}, {backgroundColor: 'black'},
a.relative,
]}> ]}>
<ExternalEmbedRemoveBtn onRemove={clear} /> <ExternalEmbedRemoveBtn onRemove={clear} />
<video <video
ref={ref} ref={ref}
src={video.uri} src={video.uri}
style={{width: '100%', height: '100%', objectFit: 'cover'}} style={{width: '100%', height: '100%', objectFit: 'cover'}}
autoPlay autoPlay={!autoplayDisabled}
loop loop
muted muted
playsInline playsInline
/> />
{autoplayDisabled && (
<View style={[a.absolute, a.inset_0, a.justify_center, a.align_center]}>
<PlayButtonIcon size={48} />
</View>
)}
</View> </View>
) )
} }

View File

@ -111,9 +111,9 @@ export function Controls({
// autoplay/pause based on visibility // autoplay/pause based on visibility
const autoplayDisabled = useAutoplayDisabled() const autoplayDisabled = useAutoplayDisabled()
useEffect(() => { useEffect(() => {
if (active && !autoplayDisabled) { if (active) {
if (onScreen) { if (onScreen) {
play() if (!autoplayDisabled) play()
} else { } else {
pause() pause()
} }
@ -151,10 +151,11 @@ export function Controls({
const onPressEmptySpace = useCallback(() => { const onPressEmptySpace = useCallback(() => {
if (!focused) { if (!focused) {
drawFocus() drawFocus()
if (autoplayDisabled) play()
} else { } else {
togglePlayPause() togglePlayPause()
} }
}, [togglePlayPause, drawFocus, focused]) }, [togglePlayPause, drawFocus, focused, autoplayDisabled, play])
const onPressPlayPause = useCallback(() => { const onPressPlayPause = useCallback(() => {
drawFocus() drawFocus()
@ -240,7 +241,8 @@ export function Controls({
}, []) }, [])
const showControls = const showControls =
(focused && !playing) || (interactingViaKeypress ? hasFocus : hovered) ((focused || autoplayDisabled) && !playing) ||
(interactingViaKeypress ? hasFocus : hovered)
return ( return (
<div <div
@ -273,7 +275,10 @@ export function Controls({
? msg`Pause video` ? msg`Pause video`
: msg`Play video`, : msg`Play video`,
)} )}
style={[a.flex_1, web({cursor: showCursor ? 'pointer' : 'none'})]} style={[
a.flex_1,
web({cursor: showCursor || !playing ? 'pointer' : 'none'}),
]}
onPress={onPressEmptySpace} onPress={onPressEmptySpace}
/> />
{!showControls && !focused && duration > 0 && ( {!showControls && !focused && duration > 0 && (

View File

@ -108,7 +108,7 @@ export function AccessibilitySettingsScreen({}: Props) {
<View style={[pal.view, styles.toggleCard]}> <View style={[pal.view, styles.toggleCard]}>
<ToggleButton <ToggleButton
type="default-light" type="default-light"
label={_(msg`Disable autoplay for GIFs`)} label={_(msg`Disable autoplay for videos and GIFs`)}
labelType="lg" labelType="lg"
isSelected={autoplayDisabled} isSelected={autoplayDisabled}
onPress={() => setAutoplayDisabled(!autoplayDisabled)} onPress={() => setAutoplayDisabled(!autoplayDisabled)}