我目前在没有播放控件的情况下循环播放我的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)
}
}
答案 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
}
}