iOS play video without audio session

2019-07-21 08:48发布

问题:

I am trying to play a short video in my app using either a MPMoviePlayerController or an AVPlayer. The problem is (since my video doesn't have any sound) that I do not want to interfere with the sounds being played by other apps in the background. I tried to play with AVAudioSession:

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryAmbient  withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
[audioSession setActive:YES error:nil];

but I had no luck. As soon as the video starts playing, the music in the background stops. I even tryied to set the audio session inactive:

   [[AVAudioSession sharedInstance] setActive:NO withOptions: AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

but in this case the sound stops for half a second and then resumes and the video player stops playing. Is there any way I can achieve what I am trying to do? Thanks.

回答1:

I assume this is not relevant anymore for you, but can be relevant for somebody else.

There is nothing much to do, but here is some workaround. The point is, when you initialise the video player, set the audio session category to ambient, in this case it will not interrupt audio sessions in other apps. Then, if you will need to "unmute" the video, you can set audio session category to default (solo ambient). It will interrupt audio sessions in other apps and will resume playing the video with sound.

Example:

- (void)initPlayer {

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient withOptions:0 error:nil];

    // some init logic
    // e.g:
    //
    // _playerItem = [AVPlayerItem playerItemWithAsset:[AVAsset assetWithURL:_URL]];
    // _player = [AVPlayer playerWithPlayerItem:_playerItem];
    // _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
    //
    // etc.

}

- (void)setMuted:(BOOL)muted {
    if (!muted) {
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient withOptions:0 error:nil];
    }

    self.player.muted = muted;
}

P.S. I assume, FB app is making something similar: when video starts playing muted, it will not interrupt others apps audio, but when user presses on video, it will go fullscreen with sound, at this point there will be active audio session of that video, and all other apps will stop playing audio.



回答2:

Are you testing with your music bkg app? If not then probably the answer is that the most music apps contain:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(handleAudioSessionInterruption:)
                                             name:AVAudioSessionInterruptionNotification
                                           object:aSession];

and implementation like:

- (void) handleAudioSessionInterruption:(NSNotification*)notification
{
    NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
   .....code....

    switch (interruptionType.unsignedIntegerValue) {
        case AVAudioSessionInterruptionTypeBegan:{
            // stop playing
        } break;
        case AVAudioSessionInterruptionTypeEnded:{
            // continue playing
        } break;
        default:
            break;
    }
}

So they stop playback and start it when the interruption is over. (for incoming calls etc)