Skip to content

Commit

Permalink
[Video] More tweaks to AVAudioSession options (#4910)
Browse files Browse the repository at this point in the history
  • Loading branch information
haileyok authored Aug 9, 2024
1 parent dd0d50a commit 5bfe5aa
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 10 deletions.
3 changes: 2 additions & 1 deletion modules/expo-bluesky-swiss-army/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as PlatformInfo from './src/PlatformInfo'
import {AudioCategory} from './src/PlatformInfo/types'
import * as Referrer from './src/Referrer'
import * as SharedPrefs from './src/SharedPrefs'
import VisibilityView from './src/VisibilityView'

export {PlatformInfo, Referrer, SharedPrefs, VisibilityView}
export {AudioCategory, PlatformInfo, Referrer, SharedPrefs, VisibilityView}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,26 @@ public class ExpoPlatformInfoModule: Module {
return UIAccessibility.isReduceMotionEnabled
}

Function("setAudioCategory") { (audioCategoryString: String) in
let audioCategory = AVAudioSession.Category(rawValue: audioCategoryString)
try? AVAudioSession.sharedInstance().setCategory(audioCategory)
}

Function("setAudioMixWithOthers") { (mixWithOthers: Bool) in
var options: AVAudioSession.CategoryOptions
let currentCategory = AVAudioSession.sharedInstance().category
if mixWithOthers {
options = [.mixWithOthers]
} else {
options = []
options = [.duckOthers]
}
try? AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: .default, options: options)
try? AVAudioSession
.sharedInstance()
.setCategory(
currentCategory,
mode: .default,
options: options
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {Platform} from 'react-native'
import {requireNativeModule} from 'expo-modules-core'

import {AudioCategory} from './types'

const NativeModule = requireNativeModule('ExpoPlatformInfo')

export function getIsReducedMotionEnabled(): boolean {
Expand All @@ -11,3 +13,8 @@ export function setAudioMixWithOthers(mixWithOthers: boolean): void {
if (Platform.OS !== 'ios') return
NativeModule.setAudioMixWithOthers(mixWithOthers)
}

export function setAudioCategory(audioCategory: AudioCategory): void {
if (Platform.OS !== 'ios') return
NativeModule.setAudioCategory(audioCategory)
}
14 changes: 14 additions & 0 deletions modules/expo-bluesky-swiss-army/src/PlatformInfo/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import {NotImplementedError} from '../NotImplemented'
import {AudioCategory} from './types'

export function getIsReducedMotionEnabled(): boolean {
throw new NotImplementedError()
}

/**
* Set whether the app's audio should mix with other apps' audio.
* @param mixWithOthers
*/
export function setAudioMixWithOthers(mixWithOthers: boolean): void {
throw new NotImplementedError({mixWithOthers})
}

/**
* Set the audio category for the app.
* @param audioCategory
* @platform ios
*/
export function setAudioCategory(audioCategory: AudioCategory): void {
throw new NotImplementedError({audioCategory})
}
5 changes: 5 additions & 0 deletions modules/expo-bluesky-swiss-army/src/PlatformInfo/index.web.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {NotImplementedError} from '../NotImplemented'
import {AudioCategory} from './types'

export function getIsReducedMotionEnabled(): boolean {
if (typeof window === 'undefined') {
Expand All @@ -10,3 +11,7 @@ export function getIsReducedMotionEnabled(): boolean {
export function setAudioMixWithOthers(mixWithOthers: boolean): void {
throw new NotImplementedError({mixWithOthers})
}

export function setAudioCategory(audioCategory: AudioCategory): void {
throw new NotImplementedError({audioCategory})
}
15 changes: 15 additions & 0 deletions modules/expo-bluesky-swiss-army/src/PlatformInfo/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Sets the audio session category on iOS. In general, we should only need to use this for the `playback` and `ambient`
* categories. This enum however includes other categories that are available in the native API for clarity and
* potential future use.
* @see https://developer.apple.com/documentation/avfoundation/avaudiosession/category
* @platform ios
*/
export enum AudioCategory {
Ambient = 'AVAudioSessionCategoryAmbient',
Playback = 'AVAudioSessionCategoryPlayback',
_SoloAmbient = 'AVAudioSessionCategorySoloAmbient',
_Record = 'AVAudioSessionCategoryRecord',
_PlayAndRecord = 'AVAudioSessionCategoryPlayAndRecord',
_MultiRoute = 'AVAudioSessionCategoryMultiRoute',
}
3 changes: 2 additions & 1 deletion src/App.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import {Provider as PortalProvider} from '#/components/Portal'
import {Splash} from '#/Splash'
import {Provider as TourProvider} from '#/tours'
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
import {PlatformInfo} from '../modules/expo-bluesky-swiss-army'
import {AudioCategory, PlatformInfo} from '../modules/expo-bluesky-swiss-army'

SplashScreen.preventAutoHideAsync()

Expand Down Expand Up @@ -158,6 +158,7 @@ function App() {
const [isReady, setReady] = useState(false)

React.useEffect(() => {
PlatformInfo.setAudioCategory(AudioCategory.Ambient)
PlatformInfo.setAudioMixWithOthers(true)
initPersistedState().then(() => setReady(true))
}, [])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {android, atoms as a, useTheme} from '#/alf'
import {Mute_Stroke2_Corner0_Rounded as MuteIcon} from '#/components/icons/Mute'
import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as UnmuteIcon} from '#/components/icons/Speaker'
import {Text} from '#/components/Typography'
import {PlatformInfo} from '../../../../../../modules/expo-bluesky-swiss-army'
import {
AudioCategory,
PlatformInfo,
} from '../../../../../../modules/expo-bluesky-swiss-army'

export function VideoEmbedInnerNative() {
const player = useVideoPlayer()
Expand All @@ -39,10 +42,12 @@ export function VideoEmbedInnerNative() {
style={a.flex_1}
nativeControls={true}
onEnterFullscreen={() => {
PlatformInfo.setAudioCategory(AudioCategory.Playback)
PlatformInfo.setAudioMixWithOthers(false)
player.muted = false
}}
onExitFullscreen={() => {
PlatformInfo.setAudioCategory(AudioCategory.Ambient)
PlatformInfo.setAudioMixWithOthers(true)
player.muted = true
}}
Expand Down Expand Up @@ -96,12 +101,16 @@ function Controls({
}
}, [player])

const toggleSound = useCallback(() => {
const newValue = !player.muted
const toggleMuted = useCallback(() => {
const muted = !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
const mix = !muted
const category = muted ? AudioCategory.Ambient : AudioCategory.Playback

PlatformInfo.setAudioCategory(category)
PlatformInfo.setAudioMixWithOthers(mix)
player.muted = muted
}, [player])

return (
Expand Down Expand Up @@ -140,7 +149,7 @@ function Controls({
accessibilityRole="button"
/>
<Pressable
onPress={toggleSound}
onPress={toggleMuted}
style={{
backgroundColor: 'rgba(0, 0, 0, 0.75)',
borderRadius: 6,
Expand Down

0 comments on commit 5bfe5aa

Please sign in to comment.