问题
I'm extremely new to Swift and iOS development, so please forgive my ignorance.
I'm trying to have the AVPlayer close automatically when the video is done playing. I've thought to attach the "playerDidFinishPlaying" listener to receive the notification, but once I have it, I can't find the method/event to close the Controller. I'm looking to mimic the action of clicking the "Done" button.
Here is a small snippet of code. Hopefully this is enough information. If not, I can provide further info
let destination = segue.destinationViewController as! AVPlayerViewController
let url = NSURL(string: "video url")
destination.player = AVPlayer(URL: url!)
destination.player?.play()
I've added the following notification, but again, I'm not sure what to do with it once I have it...
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: destination.player!.currentItem)
func playerDidFinishPlaying(note:NSNotification){
print("finished")
// close window/controller
}
Lastly, I know I'll need to remove the observer, but I'm not sure when or where to do so. Any help is greatly appreciated.
回答1:
In order to "close" the controller, you should call dismissViewControllerAnimated(true, completion: nil)
So the code will look like:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: destination.player!.currentItem)
func playerDidFinishPlaying(note:NSNotification){
print("finished")
dismissViewControllerAnimated(true, completion: nil)
}
if your viewController
is inside of a UINavigationController
stack, you can also do:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: destination.player!.currentItem)
func playerDidFinishPlaying(note:NSNotification){
print("finished")
navigationController?.popViewControllerAnimated(true)
}
And for remove the observer, you can do within deinit{}
:
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
回答2:
for #iOS 11
and swift 4.2
dismiss controller are not work so just add this key in your player setup code
if #available(iOS 11.0, *) {
self.playerVC?.exitsFullScreenWhenPlaybackEnds = true
}
if you wan to allow #iOS 10
as well then write this line.
if #available(iOS 11.0, *) {
self.playerVC?.exitsFullScreenWhenPlaybackEnds = true
}
NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemDidReachEnd(notification:)), name: .AVPlayerItemDidPlayToEndTime, object:self.playerVC?.player!.currentItem)
func playerItemDidReachEnd(note:NSNotification){
print("finished")
dismissViewControllerAnimated(true, completion: nil)
}
回答3:
Update for SWIFT 3:
Notes: The viewController where you are playing the audio needs: AVAudioPlayerDelegate
Also you dont need an observer
class myViewController: UIViewController, AVAudioPlayerDelegate {
var audioplayer = AVAudioPlayer()
override func viewDidAppear(_ animated: Bool) {
if soundsON{
let myFilePathString = Bundle.main.path(forResource: "backgroundSound", ofType: "mp3")
if let myFilePathString = myFilePathString
{
let myFilePathURL = URL(fileURLWithPath: myFilePathString)
do{
try audioplayer = AVAudioPlayer(contentsOf: myFilePathURL)
audioplayer.delegate = self
audioplayer.prepareToPlay()
audioplayer.play()
}catch{
print("error playing coin sound")
}
}
}
}
In this example the sound will play at viewDidAppear, and when it finishes it will call: audioPlayerDidFinishPlaying:
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
//Check if the sound that finishes comes from a certain AVAudioPlayer
if player == audioplayer{
print("The sound from -audioplayer- has finished")
// If you need to dismiss the VC:
dismiss(animated: true, completion: nil)
}
}
来源:https://stackoverflow.com/questions/35048758/swift-avplayeritem-close-when-finished