Paulos Ab
Paulos Ab

Reputation: 399

Expo AV Audio not audible on ios

Hi everyone I am using Expo AV to play sounds in my React Native (Expo-managed) app, the audio plays well and audibly on android but it doesn't play loudly and audibly on ios, and apple also rejected the app on App Store because of this

they said

Your app declares support for audio in the UIBackgroundModes key in your Info.plist but did not include features that require persistent audio.
Next Steps
The audio key is intended for use by apps that provide audible content to the user while in the background, such as music player or streaming audio apps. Please revise your app to provide audible content to the user while the app is in the background or remove the "audio" setting from the UIBackgroundModes key.

and this is the expo-av audio mode settings

Audio.setAudioModeAsync({
        staysActiveInBackground: true,
        shouldDuckAndroid: true,
        interruptionModeIOS: 1,
        interruptionModeAndroid: 1,
        allowsRecordingIOS: true,
        playsInSilentModeIOS: false,
})

and I play the audio like so

const {sound} = await Audio.Sound.createAsync(
          {uri: audioURI},
          {
            shouldPlay: true,
          }
        );

and this is the import statement

import { Audio } from 'expo-av';

and I don't know if it was caused by the React Native Music Control library I am using for the Music control in the app

imported like

import MusicControl from 'react-native-music-control'

and I call it immediately after playing the audio

MusicControl.setNowPlaying({
            title: currentAudio.title,
            artwork: currentAudio.imageUrl, // URL or RN's image require()
            artist: currentAudio.artist,
            genre: currentAudio.genre,
            duration: (minutesToMilliseconds(currentAudio.playtime) / 1000), // (Seconds)
            description: currentAudio.description, // Android Only
            color: 0xffffff, // Android Only - Notification Color
            colorized: true, // Android 8+ Only - Notification Color extracted from the artwork. Set to false to use the color property instead
            isLiveStream: false, // iOS Only (Boolean), Show or hide Live Indicator instead of seekbar on lock screen for live streams. Default value is false.
        })

please what I'm I doing wrong, thanks in advance for the help

Upvotes: 3

Views: 1334

Answers (1)

Paulos Ab
Paulos Ab

Reputation: 399

I have fixed it

How?

I think it was the react-native-music-control that was causing it, I did the configuration of Expo AV Audio and react-native-music-control in a function and called the function in a React.useLayoutEffect in one of the main files of the app

but I discovered that if I changed something in the function, the audio get audible

so what I did was to call the function after calling Audio.Sound.createAsync(...)

const {sound} = await Audio.Sound.createAsync(
 { uri: audioDetails.url, },
           {
             shouldPlay: true,
           },
           (status: AVPlaybackStatus) => 
           onPlaybackStatusUpdate(...),
           false
          
         );
       useAppGlobalContextIn.initializeMusicControl() // the function where I called the Expo AV Audio and the MusicControl setup

the function

const initializeMusicControl = React.useCallback(() => {
MusicControl.setCustomNotificationIcon(require('./assets/icon.png'))
MusicControl.enableBackgroundMode(true);
MusicControl.handleAudioInterruptions(true);
    // // // Basic Controls
MusicControl.enableControl('play', true)
MusicControl.enableControl('pause', true)
MusicControl.enableControl('stop', true)
MusicControl.enableControl('nextTrack', true)
MusicControl.enableControl('previousTrack', true)

    // // // Changing track position on lockscreen
MusicControl.enableControl('changePlaybackPosition', true)

    // // Seeking
MusicControl.enableControl('seekForward', false) // iOS only
MusicControl.enableControl('seekBackward', false) // iOS only
MusicControl.enableControl('skipForward', false)
MusicControl.enableControl('skipBackward', false)
    
    // // Android Specific Options
MusicControl.enableControl('seek', true) // Android only
MusicControl.enableControl('setRating', false)
MusicControl.enableControl('volume', true) // Only affected when remoteVolume is enabled
MusicControl.enableControl('remoteVolume', true)
 MusicControl.enableControl('closeNotification', true, { when: 'always' })



    // // // iOS Specific Options
MusicControl.enableControl('enableLanguageOption', false)
MusicControl.enableControl('disableLanguageOption', false)

Audio.setAudioModeAsync({
     staysActiveInBackground: true,
     shouldDuckAndroid: true,
     interruptionModeIOS: 1,
     interruptionModeAndroid: 1,
     allowsRecordingIOS: true,
     playsInSilentModeIOS: true,
 })
}, [])

then I called it like so

React.useLayoutEffect(() => {
initializeMusicControl()
}, [])

it kind of tricky, but when I ran across another issue with Expo AV Audio, I decided to change to react-native-track-player and it works perfectly, it handles both the function of Expo AV Audio and react-native-music-control and also provides incredible events to work with remote events

Upvotes: 0

Related Questions