Search code examples
swiftmpmovieplayercontrolleravplayeravplayerlayer

Disable Audio (and interruption) with MPMoviePlayerController using Swift


At the moment, this is how I'm playing a video on the subview of my UIViewController:

override func viewDidAppear(animated: Bool)  {
    let filePath = NSBundle.mainBundle().pathForResource("musicvideo", ofType: "mp4")
    self.moviePlayerController.contentURL = NSURL.fileURLWithPath(filePath)
    self.moviePlayerController.play()
    self.moviePlayerController.repeatMode = .One
    self.moviePlayerController.view.frame = self.view.bounds
    self.moviePlayerController.scalingMode = .AspectFill
    self.moviePlayerController.controlStyle = .None
    self.moviePlayerController.allowsAirPlay = false
    self.view.addSubview(self.moviePlayerController.view)
}

I've read on ways to disable the audio by doing the following below (none of which work, at all). Keep in mind I'm trying to disable it to the point of not interrupting the current music playing via the Music app, Spotify, etc.

// Playing media items with the applicationMusicPlayer will restore the user's Music state after the application quits.

// The current volume of playing music, in the range of 0.0 to 1.0.
// This property is deprecated -- use MPVolumeView for volume control instead.

1) MPMusicPlayerController.applicationMusicPlayer().volume = 0

2) MPVolumeView doesn't even have a setting for setting the actual volume? It's a control.

3) self.moviePlayerController.useApplicationAudioSession = false


Solution

  • So I found this answer.

    This is my Swift code that I ended up going with. I then used an AVPlayerLayer to add to the view as a sublayer, which works perfectly.

    Thanks to the OP who managed to get a hold of an Apple technician and provided the original Objective-C code.

    The only problems I'm facing now is that it:

    1) Interrupts current music playback, whether it's from Music, Spotify, etc.

    2) Video stops playing if I close the app and open it up again.

    override func viewDidAppear(animated: Bool)  {
        let filePath = NSBundle.mainBundle().pathForResource("musicvideo", ofType: "mp4")
    
        var asset: AVURLAsset?
        asset = AVURLAsset.URLAssetWithURL(NSURL.fileURLWithPath(filePath), options: nil)
        var audioTracks = NSArray()
        audioTracks = asset!.tracksWithMediaType(AVMediaTypeAudio)
    
        // Mute all the audio tracks
        let allAudioParams = NSMutableArray()
        for track: AnyObject in audioTracks {
            // AVAssetTrack
            let audioInputParams = AVMutableAudioMixInputParameters()
            audioInputParams.setVolume(0.0, atTime: kCMTimeZero)
            audioInputParams.trackID = track.trackID
            allAudioParams.addObject(audioInputParams)
        }
    
        let audioZeroMix = AVMutableAudioMix()
        audioZeroMix.inputParameters = allAudioParams
    
        // Create a player item
        let playerItem = AVPlayerItem(asset: asset)
        playerItem.audioMix = audioZeroMix
    
        // Create a new Player, and set the player to use the player item
        // with the muted audio mix
        let player = AVPlayer.playerWithPlayerItem(playerItem) as AVPlayer
    
        player.play()
    
        let layer = AVPlayerLayer(player: player)
        player.actionAtItemEnd = .None
    
        layer.frame = self.view.bounds
        layer.videoGravity = AVLayerVideoGravityResizeAspectFill
        self.view.layer.addSublayer(layer)
    }