Turn off audio playback of AVPlayer?

Gaby Fitcal picture Gaby Fitcal · Aug 5, 2015 · Viewed 14.5k times · Source

I have a AVPlayer with AVPlayerItem. What i want is to turn off the audio playback off AVPlayer. I want play just video.

Can someone help me? Thank you!

    self.avPlayerItem = [AVPlayerItem playerItemWithURL:self.videoUrl];
    self.avPlayer = [AVPlayer playerWithPlayerItem:self.avPlayerItem];
    [self.avPlayer play];
    self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;


    self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
    self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidPlayToEndTime:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:self.avPlayerItem];


    CGRect screenRect = [[UIScreen mainScreen] bounds];

    self.avPlayerLayer.frame = CGRectMake(0, 0, screenRect.size.width , screenRect.size.height );
    [self.view.layer insertSublayer:self.avPlayerLayer atIndex:0];

Answer

AnBisw picture AnBisw · Apr 29, 2018

As @Tung Fam's answer suggests, you can easily do this in your App to mute a video-

player.isMuted = true

Handling all the Use Cases:

You may run a video on mute using the code above, the problem is, if you simply use isMuted = true (for let's say the video preview) it will work, but your app will "hijack" the AVAudioSession from the Operating system, which means if the user was, lets say, listening to music (spotify or apple music), their music would get interrupted. That is because your App will have a default setup of AVAudioSession to AVAudioSessionCategorySoloAmbient , which means that your app will ALWAYS interrupt all audio sessions that is running in the background as soon as it starts playing a video, muted or un-muted. This may not be a very pleasing user experience and lead to confusion.

What you may want to do is, show your video muted as a preview, while the user continues to play their song in the background. When user goes to full screen with your app's video, any background audio must "pause" or be "interrupted" essentially your app taking over the AVAudioSession. And then once you are done playing your video let the "interrupted" background music (example: Spotify, Apple Music etc.) to resume. The steps below achieves exactly how Twitter's app handles videos and background music-

  1. In your AppDelegate in didFinishLaunchingWithOptions method make sure your app is not interrupting any background music. Now since your videos would be running in "mute" you can simply mixWithOthers.

     do{
      try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers])
      try AVAudioSession.sharedInstance().setActive(true)
    }catch{//some meaningful exception handling}
    
  2. When your App starts to play your video Full screen (un-muted/with sound), you must now interrupt any background music. For that, before your player.play() you can set the AVAudioSession again, like so-

    do{
         try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: [])
         try AVAudioSession.sharedInstance().setActive(true)
     }catch{//some meaningful exception handling}
    

    this will basically pause/interrupt any background audio in progress and let your video play with sound.

  3. Once your video is done playing with sound, you must now let the AVAudioSession know that it can resume any audio session that was interrupted by you (i.e. Spotify, apple music, map navigation instructions etc.). To do that, once your video stops playing you can do this-

    do{
          try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers])
          try AVAudioSession.sharedInstance().setActive(false, with: AVAudioSessionSetActiveOptions.notifyOthersOnDeactivation)
       }catch{//some meaningful exception handling}
    

There's a lot more options available on how to handle AVAudioSession and here's the documentation. And here are Apple's guidelines on using AVAudioSession for different type of apps.


This is just a very basic explanation on how AVAudioSession can be used, but depending on your app's functionality there may be a need to use KVOs, AppDelegate methods (for app going to background and or coming to foreground and so on) to set the AVAudioSession appropriately. Further caveat is that you really need to play around with all the options on AVAudioSession since it may not work the way you think it should so it could become a little grueling. Even more caveat is that surprisingly i've found very little online that goes into detail with AVAudioSession except for Apple's documentation and a few questions here on SO here and there. Bottom line is - if your app deals with Audio/Videos then it is HIGHLY recommended to handle AVAudioSession appropriately based on Apple's playbook of "Audio Guidelines By App Type", maybe not when you launch your app but definitely as your app matures and becomes more stable.