Impossible to stop AVPlayer
If you declare player
as an optional variable, you can then set the player to nil
to deallocate it.
Silly example but it shows what happens:
import UIKit
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var btnPlay: UIButton!
var player:AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func btnPress(sender: AnyObject) {
if (btnPlay.titleLabel?.text == "Play") {
initPlayer()
btnPlay.setTitle("Stop", forState: UIControlState.Normal)
} else {
stopPlayer()
btnPlay.setTitle("Play", forState: UIControlState.Normal)
}
}
func initPlayer() {
if let play = player {
print("playing")
play.play()
} else {
print("player allocated")
player = AVPlayer(URL: NSURL(string: "http://streaming.radio.rtl.fr/rtl-1-48-192")!)
print("playing")
player!.play()
}
}
func stopPlayer() {
if let play = player {
print("stopped")
play.pause()
player = nil
print("player deallocated")
} else {
print("player was already deallocated")
}
}
}
How to stop a video in AVPlayer?
AVPlayer does not have a method named stop
. You can pause
or set rate
to 0.0.
Is it possible to force AVPlayer stop playing video externally (on Apple TV)
First you'd have to read this reference on programming multiple displays.
But in this specific situation I think, you are looking for [UIScreen screens]
which returns an NSArray
of UIScreen
objects. The UIScreen
with index 0 is the internal display and the one with the index 1 is the Apple TV's display. From now on, according to this documentation and its examples you only need to create a UIWindow
which has the screen property of the UIScreen
you want to display on. Then you can easily add layers, views, etc. to that UIWindow.
AVPlayer stops playing and doesn't resume again
Yes, it stops because the buffer is empty so it has to wait to load more video. After that you have to manually ask for start again. To solve the problem I followed these steps:
1) Detection: To detect when the player has stopped I use the KVO with the rate property of the value:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"rate"] )
{
if (self.player.rate == 0 && CMTimeGetSeconds(self.playerItem.duration) != CMTimeGetSeconds(self.playerItem.currentTime) && self.videoPlaying)
{
[self continuePlaying];
}
}
}
This condition: CMTimeGetSeconds(self.playerItem.duration) != CMTimeGetSeconds(self.playerItem.currentTime)
is to detect the difference between arriving at the end of the video or stopping in the middle
2) Wait for the video to load - If you continue playing directly you will not have enough buffer to continue playing without interruption. To know when to start you have to observe the value playbackLikelytoKeepUp
from the playerItem (here I use a library to observe with blocks but I think it makes the point):
-(void)continuePlaying
{
if (!self.playerItem.playbackLikelyToKeepUp)
{
self.loadingView.hidden = NO;
__weak typeof(self) wSelf = self;
self.playbackLikelyToKeepUpKVOToken = [self.playerItem addObserverForKeyPath:@keypath(_playerItem.playbackLikelyToKeepUp) block:^(id obj, NSDictionary *change) {
__strong typeof(self) sSelf = wSelf;
if(sSelf)
{
if (sSelf.playerItem.playbackLikelyToKeepUp)
{
[sSelf.playerItem removeObserverForKeyPath:@keypath(_playerItem.playbackLikelyToKeepUp) token:self.playbackLikelyToKeepUpKVOToken];
sSelf.playbackLikelyToKeepUpKVOToken = nil;
[sSelf continuePlaying];
}
}
}];
}
And that's it! problem solved
Edit: By the way the library used is libextobjc
Swift AVPlayer How To Stop Automatically When Audio Finished
You can use the NSNotificationCenter Observer
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: item)
player?.play()
and stop player in this function
func playerDidFinishPlaying(note: NSNotification) {
// Your code here
player?.pause()
player?.replaceCurrentItem(with: nil)
}
iOS AVPlayer cancel buffering
So the correct answer is @Che with:
If you will call [self.player replaceCurrentItemWithPlayerItem:nil];
buffering stops. – Che Oct 13 at 14:36
and you do so on the observer listening for the status update from the playerWithPlayerItem. Thanks All!
Related Topics
How to Add Line Break for Uilabel
Adding Blur Effect to Background in Swift
Pod Install Is Staying on "Setting Up Cocoapods Master Repo"
Uicollectionview Spacing Margins
Add a Uiview Above All, Even the Navigation Bar
Changing Placeholder Text Color with Swift
App Installation Failed Due to Application-Identifier Entitlement
Xcode iOS Project Only Shows "My MAC 64-Bit" But Not Simulator or Device
Programmatically Scroll a Uiscrollview
Libraries Not Found When Using Cocoapods with iOS Logic Tests
How Does Xcode Find Implicit Target Dependencies
Decimal to Fraction Conversion in Swift
Could Not Load the "" Image Referenced from a Nib in the Bundle with Identifier
Swiftui: What Is @Appstorage Property Wrapper
Keyboard and Cursor Show, But I Can't Type Inside Uitextfields and Uitextviews
Expand Uilabel Inside Uitableview with "More" Button Like Instagram
You Are Not Authorised to Use This Service Itunes App Upload Error