2
votes

My app plays a video and occasionally has verbal queues. When there is nothing being said by the app, I want the audio (in the background say from Spotify or iTunes) to come back to full volume. When there is audio I want the audio to dim.

I have set the audio session to DuckOthers.

The problem is, whenever I restore the background audio:

class func restoreBackgroundAudio()
{
    do {
        try AVAudioSession.sharedInstance().setActive(false)
    } catch _ {
        print("ERROR restoring background audio")
    }
}

I get this error:

[0x1a03a9000] AVAudioSession.mm:697: -[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.

The problem is that the video file that is playing seems to have an audio that I cannot mute.

I have tried the following:

  1. I removed the audio track from the video and tried playing it in an MPMoviePlayerController

    _movie                                = MPMoviePlayerController()
    _movie.controlStyle                   = MPMovieControlStyle.None
    _movie.view.frame                     = _movieView.frame
    _movie.repeatMode                     = MPMovieRepeatMode.One
    _movie.backgroundView.backgroundColor = UIColor.whiteColor()
    _movie.contentURL = NSURL(fileURLWithPath: documentsDirectory.stringByAppendingString("/\(videoName)"))
     _movie.play()
    

Every time the movie plays its loop it forces the background audio to dim even though I am not setting AVAudioSession.sharedInstance().setActive(true)

  1. Making my own AVPlayerItem and AVPlayer, and manually muting the audio tracks inside the AVPlayerItem as well as setting the AVPlayer to muted:

        var asset = AVURLAsset(URL: _movieURL)
        var audioTracks = asset.tracksWithMediaType(AVMediaTypeAudio)
        // Set the volume of ANY potential audio track to 0
        var allAudioParams:[AVMutableAudioMixInputParameters] = []
        for track:AVAssetTrack in audioTracks
        {
            var audioInputParams = AVMutableAudioMixInputParameters()
            audioInputParams.setVolume(0.0, atTime: kCMTimeZero)
            audioInputParams.trackID = track.trackID
            allAudioParams.append(audioInputParams)
        }
    
        var muteTrack = AVMutableAudioMix()
        muteTrack.inputParameters = allAudioParams
    
        var item:AVPlayerItem = AVPlayerItem(URL: _movieURL)
        // Assign the muted audio track
        item.audioMix = muteTrack
    
        _avPlayer = AVPlayer(playerItem: item)
        // Also set the AVPlayer to be muted
        _avPlayer.muted = true
        let playerLayer = AVPlayerLayer(player: _avPlayer)
        playerLayer.frame = _movie.view.frame
        layer.addSublayer(playerLayer)
    
        _avPlayer.play() // ALWAYS DIMS BACKGROUND AUDIO!
    

Again, once the video loops it always dims the background audio. I tried hacking it and doing a restoreBackgroundAudio() call right after I hit the play button, but I get a bad fade in and out and in and out effect like its trying to restore the background audio but the active video player is forcing the dim as an override.

If you have any suggestions on what else I can do to either actually mute a video thats playing or play a video that doesnt dim the background I would appreciate it.

2
Can you not simply set the _avPlayer.volume = 0; that works.user3069232
That has no effect. Even at volume 0 background audio dimsAggressor
You know, to solve this issue I would go back to basics. Implement each of these thing separately and set your volume controls; and then try merging them again.user3069232
I've tried all of that, I am posting this question in hopes of a more technical solution someone might have.Aggressor
MPVolumeView might be the answer: I frequently find myself not actually logging an SO question, cause as I typing it in; I alway check the suggestions it makes before press post; I do now anyway. Any look at this one; I know its old but stackoverflow.com/questions/11095644/…user3069232

2 Answers

0
votes

I understand the main problem is, that when AVPlayer plays video, even if it is muted, it will stop background music from other apps.

It is the default behaviour of the AVAudioSession manager. What I do not understand is why AVAudioSession manager "kills" background music even if there is no sound output in action (AVPlayer is muted). This behaviour is also problem for me.

Here is what I suggest to do in this case.

And here you can read about AVAudioSession management.

0
votes

You will need to use this to allow mixing of your app audio with other apps audio:

NSError *silentSwitcherror = nil;
BOOL silentSwitchSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&silentSwitcherror];
if (silentSwitchSuccess) {
//insert video player code here to play video
}
else
{
//insert video player code here to play video
}