在下一个视图控制器

时间:2018-02-12 02:17:43

标签: ios swift xcode video avplayer

我目前在没有播放控件的情况下循环播放我的mp4视频,有点像gif但有声音。但我不知道为什么当我转到下一个视图控制器时,视频仍在播放。有人知道解决这个问题的最简单方法吗?

的ViewController

import UIKit
import AVKit
import AVFoundation
fileprivate var playerObserver: Any?


class ScoreController: UIViewController {
    @IBOutlet var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()


        let returnValue: Int = UserDefaults.standard.integer(forKey: "userScore")
        label.text = "Your Score: \(returnValue)/30"

        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            let path = Bundle.main.path(forResource: "Innie-Kiss", ofType:"mp4")
            let player = AVPlayer(url: URL(fileURLWithPath: path!))
            let resetPlayer = {
                player.seek(to: kCMTimeZero)
                player.play()
            }
            playerObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: nil) { notification in resetPlayer() }
            let controller = AVPlayerViewController()
            controller.player = player
            controller.showsPlaybackControls = false
            self.addChildViewController(controller)
            let screenSize = UIScreen.main.bounds.size
            let videoFrame = CGRect(x: 0, y: 130, width: screenSize.width, height: (screenSize.height - 130) / 2)
            controller.view.frame = videoFrame
            self.view.addSubview(controller.view)
            player.play()
        } catch {
        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    }
    fileprivate var player: AVPlayer? {
        didSet { player?.play() }
    }
    deinit {
        guard let observer = playerObserver else { return }
        NotificationCenter.default.removeObserver(observer)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()  
    }
    @IBAction func doneButton(_ sender: Any) {
        self.performSegue(withIdentifier: "done", sender: self)
    }
}

5 个答案:

答案 0 :(得分:5)

在viewWillDisapper()或segue的按钮操作中执行以下操作:

NotificationCenter.default.removeObserver(self)

同样将它从viewDidLoad()移动到某个函数,如:

var player: AVPlayer?

func audioPlayer(){
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        let path = Bundle.main.path(forResource: "Innie-Kiss", ofType:"mp4")
        player = AVPlayer(url: URL(fileURLWithPath: path!))
        let resetPlayer = {
            self.player?.seek(to: kCMTimeZero)
            self.player?.play()
        }
        playerObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player?.currentItem, queue: nil) { notification in resetPlayer() }
        let controller = AVPlayerViewController()
        controller.player = player
        controller.showsPlaybackControls = false
        self.addChildViewController(controller)
        let screenSize = UIScreen.main.bounds.size
        let videoFrame = CGRect(x: 0, y: 130, width: screenSize.width, height: (screenSize.height - 130) / 2)
        controller.view.frame = videoFrame
        self.view.addSubview(controller.view)
        player?.play()
    } catch {
    }
}

并使玩家对象成为全局变量。 var player = AVPlayer?viewWillDisappear nil

所以你的viewWillDisappear应该是这样的:

override func viewWillDisappear(_ animated: Bool) {
     NotificationCenter.default.removeObserver(self)
    if player != nil{
        player?.replaceCurrentItem(with: nil)
        player = nil
    }
}

答案 1 :(得分:0)

override func viewWillDisappear(_ animated: Bool) {

    }

如果您要切换窗户,这可能对您有所帮助;当您执行segue时,您将自动执行大括号中包含的函数。我对AV很垃圾,但如果它不在IBAction中工作,那么其他一些建议关闭该功能的代码可能会在这里工作。

我对Xcode不太满意,所以里程可能会有所不同。

答案 2 :(得分:0)

我遇到了这个问题并通过在将播放器设置为nil之前添加此行来修复它:

[self.player pause];

这是我的viewWillDisapear:

- (void)viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AVPlayerItemDidPlayToEndTimeNotification
                                                  object:self.player];
    [self.player removeObserver:self forKeyPath:@"rate"];
    [self.player removeTimeObserver:self.playerObserver];
    self.playerObserver = nil;
    [self.player pause];
    self.player = nil;
    [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
    [UINavigationController attemptRotationToDeviceOrientation];
    [StayfilmApp restrictOrientation:YES];
}

答案 3 :(得分:0)

class ScoreController: UIViewController {
    @IBOutlet var label: UILabel!
    var player: AVPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()


        let returnValue: Int = UserDefaults.standard.integer(forKey: "userScore")
        label.text = "Your Score: \(returnValue)/30"

        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            let path = Bundle.main.path(forResource: "Innie-Kiss", ofType:"mp4")
            player = AVPlayer(url: URL(fileURLWithPath: path!))
            let resetPlayer = {
                player.seek(to: kCMTimeZero)
                player.play()
            }
            playerObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: nil) { notification in resetPlayer() }
            let controller = AVPlayerViewController()
            controller.player = player
            controller.showsPlaybackControls = false
            self.addChildViewController(controller)
            let screenSize = UIScreen.main.bounds.size
            let videoFrame = CGRect(x: 0, y: 130, width: screenSize.width, height: (screenSize.height - 130) / 2)
            controller.view.frame = videoFrame
            self.view.addSubview(controller.view)
            player.play()
        } catch {
        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        player.pause()
    }
    fileprivate var player: AVPlayer? {
        didSet { player?.play() }
    }
    deinit {
        guard let observer = playerObserver else { return }
        NotificationCenter.default.removeObserver(observer)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()  
    }
    @IBAction func doneButton(_ sender: Any) {
        self.performSegue(withIdentifier: "done", sender: self)
    }
}

值得注意的变化:

var player: AVPlayer?

还有

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self)
    player?.pause()
}

答案 4 :(得分:0)

当我使用segue转到下一个ViewController时,我遇到了同样的问题,然后我通过使用此代码迅速使用了当前代码

     @IBAction func next(_ sender: Any) {


            let vc = self .storyboard?.instantiateViewController(withIdentifier:"ViewControllerAA") as! ViewControllerAA
                   self.present(vc,animated: true,completion: nil)

}

但是问题没有解决,然后我使用此代码转到下一个VC,问题解决了,视频的背景声音停止了,代码如下:

 @IBAction func next(_ sender: Any) {


     if let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerAA") as? ViewControllerAA {
         let appDelegate = UIApplication.shared.delegate as! AppDelegate
         appDelegate.window?.rootViewController = vc
      }





    }