Если ваше приложение воспроизводит видео и приостанавливает фоновый звук, как вы можете возобновить воспроизведение фонового звука, когда закончите?

У меня есть приложение, в котором пользователи могут воспроизводить видео в полноэкранном режиме. Это достигается довольно просто с помощью AVPlayerViewController.

Это прекрасно работает, но в обстоятельствах, когда пользователь, скажем, слушает подкаст, если он нажмет на видео, чтобы посмотреть, подкаст приостановится, чтобы пользователь мог посмотреть видео, но когда я закрываю видео, я бы ожидать возобновления подкаста. Это поведение большинства приложений, я подтвердил это, например, в Twitter и Tweetbot. Как ни странно, приведенный ниже код работает для Apple Podcasts (он возобновится), но не для других, и другие приложения, такие как вышеупомянутый Tweetbot, работают универсально.

Однако мне абсолютно не повезло заставить это работать.

Что я пробовал:

  • Простое представление AVPlayerViewController с минимальным количеством необходимого кода: не возобновляется.
  • На viewDidDisappear из AVPlayerViewController вызов AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation): не возобновляется и выдает ошибку "игрок занят".
  • Ладно, попробуем остановить плеер вручную с помощью player?.pause() в viewDidDisappear: не возобновляет, все равно выдает ошибку "плеер занят".
  • Хм, может быть, дать ему секунду? Попробуйте позвонить setActive после DispatchQueue.main.asyncAfter 1 секунды? Нет ошибки, но не возобновляется.

Я поместил его в тестовый проект с минимальным количеством кода:

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .system)
        button.addTarget(self, action: #selector(buttoned(sender:)), for: .touchUpInside)
        button.setTitle("Tap here to view video", for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 19.0)
        button.frame = view.bounds
        view.addSubview(button)
    }

    @objc private func buttoned(sender: UIButton) {
        let videoURL = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
        let player = AVPlayer(url: videoURL!)
        let playerViewController = CustomVideoController()
        playerViewController.player = player
        self.present(playerViewController, animated: true) {
            playerViewController.player?.play()
        }
    }
}

class CustomVideoController: AVPlayerViewController {
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        do {
            try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
        } catch {
            print(error)
        }
    }
}

Вот полный компилируемый проект (буквально только приведенный выше код): https://drive.google.com/file/d/1oWb-bNIQv5B1KjMkez6BxuEIh_n6eFxH/view

Воспроизведите что-нибудь из Apple Music, Spotify, Overcast и т. д., затем запустите приложение и коснитесь просмотра видео.

Я схожу с ума, пытаясь понять эту относительно тривиальную вещь, так как я уверен, что просто делаю что-то невероятно глупое, но любая помощь будет оценена по достоинству.


person christianselig    schedule 30.01.2019    source источник


Ответы (2)


Вы пытались использовать player в качестве члена var? Таким образом, вы можете уничтожить его после исчезновения представления, еще не проверял, но код должен быть таким:

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {

    var player:AVPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .system)
        button.addTarget(self, action: #selector(buttoned(sender:)), for: .touchUpInside)
        button.setTitle("Tap here to view video", for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 19.0)
        button.frame = view.bounds
        view.addSubview(button)
    }

    @objc private func buttoned(sender: UIButton) {
        let videoURL = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
        player = AVPlayer(url: videoURL!)
        let playerViewController = CustomVideoController()
        playerViewController.player = player
        self.present(playerViewController, animated: true) {
            playerViewController.player?.play()
        }
    }
}

class CustomVideoController: AVPlayerViewController {
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        player.pause()
        player = nil
        do {
            try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
        } catch {
            print(error)
        }
    }
}
person thachnb    schedule 30.01.2019
comment
Уничтожение его, к сожалению, не дало никакого эффекта. :/ - person christianselig; 30.01.2019

(Извините, я не могу оставлять комментарии)

Пробовали ли вы тестировать на другом устройстве (с другой версией iOS?). Ваш пример кода отлично работал на моем iPhone 6 (iOS 12.1.2), я тестировал и музыку, и подкасты.

person Bill    schedule 31.01.2019
comment
Приложения от Apple, кажется, работают, но я не могу найти какие-либо сторонние приложения, которые работают. Попробуйте любое другое приложение, которое воспроизводит фоновый звук. - person christianselig; 31.01.2019