[Video] Prevent pausing of background audio with `expo-video` on iOS (#4908)

* audio mixing pref

* lint

* patch expo video to add enter/exit fullscreen events

* rm logs

* fix audio problems

* toggle mute when enter/exiting fullscreen

---------

Co-authored-by: Samuel Newman <10959775+mozzius@users.noreply.github.com>
zio/stable
Hailey 2024-08-09 03:25:54 -07:00 committed by GitHub
parent 0f993a09c2
commit dd0d50a6f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 16 additions and 2 deletions

View File

@ -61,6 +61,7 @@ import {Provider as PortalProvider} from '#/components/Portal'
import {Splash} from '#/Splash' import {Splash} from '#/Splash'
import {Provider as TourProvider} from '#/tours' import {Provider as TourProvider} from '#/tours'
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
import {PlatformInfo} from '../modules/expo-bluesky-swiss-army'
SplashScreen.preventAutoHideAsync() SplashScreen.preventAutoHideAsync()
@ -157,6 +158,7 @@ function App() {
const [isReady, setReady] = useState(false) const [isReady, setReady] = useState(false)
React.useEffect(() => { React.useEffect(() => {
PlatformInfo.setAudioMixWithOthers(true)
initPersistedState().then(() => setReady(true)) initPersistedState().then(() => setReady(true))
}, []) }, [])

View File

@ -12,6 +12,7 @@ import {android, atoms as a, useTheme} from '#/alf'
import {Mute_Stroke2_Corner0_Rounded as MuteIcon} from '#/components/icons/Mute' import {Mute_Stroke2_Corner0_Rounded as MuteIcon} from '#/components/icons/Mute'
import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as UnmuteIcon} from '#/components/icons/Speaker' import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as UnmuteIcon} from '#/components/icons/Speaker'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {PlatformInfo} from '../../../../../../modules/expo-bluesky-swiss-army'
export function VideoEmbedInnerNative() { export function VideoEmbedInnerNative() {
const player = useVideoPlayer() const player = useVideoPlayer()
@ -37,11 +38,18 @@ export function VideoEmbedInnerNative() {
player={player} player={player}
style={a.flex_1} style={a.flex_1}
nativeControls={true} nativeControls={true}
onEnterFullscreen={() => {
PlatformInfo.setAudioMixWithOthers(false)
player.muted = false
}}
onExitFullscreen={() => {
PlatformInfo.setAudioMixWithOthers(true)
player.muted = true
}}
/> />
<Controls <Controls
player={player} player={player}
enterFullscreen={() => { enterFullscreen={() => {
player.muted = false
ref.current?.enterFullscreen() ref.current?.enterFullscreen()
}} }}
/> />
@ -89,7 +97,11 @@ function Controls({
}, [player]) }, [player])
const toggleSound = useCallback(() => { const toggleSound = useCallback(() => {
player.muted = !player.muted const newValue = !player.muted
// We want to set this to the _inverse_ of the new value, because we actually want for the audio to be mixed when
// the video is muted, and vice versa.
PlatformInfo.setAudioMixWithOthers(!newValue)
player.muted = newValue
}, [player]) }, [player])
return ( return (