Why doesn't AVPlayer stop loading data? - ios

When I watch my mac's network connectivity I can tell that a movie is still buffering even after I remove the view which had the AVPlayer on it.
Does anyone know how to force AVPlayer to stop loading data?

Maybe it's late to answer this question, but I've just solved the same one.
Just save here in case anyone need...
[self.player.currentItem cancelPendingSeeks];
[self.player.currentItem.asset cancelLoading];
There's no cancel method in AVPlayer class, but in AVPlayerItem and AVAsset class, there are!
PS: player here is AVPlayer class, not AVQueuePlayer class.

An AVPlayer is not a view. You may have "removed the view" but that does not mean you have removed or stopped the AVPlayer. I would guess that the way to do what you want is to destroy the AVPlayer itself.

I figured it out.
When you want to stop an AVPlayerItem from loading, use AVQueuePlayer's removeAllItems and then re-initialize it.
[self.avPlayer removeAllItems];
self.avPlayer = [AVQueuePlayer playerWithURL:[NSURL URLWithString:#""]];
self.avPlayer = nil;
This will stop the current item from loading -- it is the only way I found to accomplish this.

Related

How to disconnect AVPlayer from AVPlayerItem?

I want to reuse an AVPlayerItem but keep getting this error:
An AVPlayerItem cannot be associated with more than one instance of AVPlayer
Before trying to reuse it, I destroy the previous AVPlayer like this:
[self.player pause];
[self.player replaceCurrentItemWithPlayerItem:nil];
self.player = nil;
why is the AVPlayerItem still associated and how can I disconnect it?
Here is a Gist with a full reproduction of the problem (only 50 lines btw): https://gist.github.com/sbiermanlytle/14a6faab515f7691b810789086ae9e50
You can run it by creating a new Single View app, and supplanting the ViewController implementation with that code.
You can't disconnect AVPlayerItems. I guess the private property that points to the player is not weak, so dereferencing the item by setting current player item to NULL does not automatically set the item's player property to NULL..
Simply create a new one. Either with the URL, in which case the cache system will return an AVAsset instantly ( Just another guess... ), or, better, with the asset of the PlayerItem you want to 'disconnect'.
AVPlayerItem* newPlayerItem = [AVPlayerItem playerItemWithAsset:playerItem.asset];
There is no performance loss doing this. The item is just a 'handle' to the asset, which contains the data for real. So don't be afraid to trash and create new items on the fly.

How to pause/resume avplayer preload

I'm using AVPlayer to play video from Internet, is there a way to pause/resume preloading video when pause/resume playing?
One way to do that would be to save your AVURLAsset to a variable (tempAsset = player.playerItem.asset), and then replace the playerItem in your player with nil. When you are ready to play it again, you can create a new playerItem from the asset that you saved previously.
I have same problem and i used buffer limit to stop preloading in my code.
This works for me.
You can also try setting buffer limit to stop preloading video when you click on Pause or Resume.
I hope this will help you.
The duration the player should buffer media from the network ahead of the playhead to guard against playback disruption.
player.currentItem?.preferredForwardBufferDuration
When you work with AVPlayerItem you can set time interval for the buffer. Example:
AVPlayerItem(). preferredForwardBufferDuration = TimeInterval(exactly: 100)!

Objective-C: Making AVPlayer plays in all the app controllers (or in the background)

I'm making a news iOS app, i want to implement a live audio streaming in all the pages like the picture below:
The orange view is a UIView that says "Live Streaming" (in Arabic), it exists in all the viewControllers, i want to let the AVPlayer plays when the user clicks on it and still plays even if the user navigates to other viewControllers.
I can't seem to find a good solution or tutorial about this, sorry if this is a noob question cause i'm new to iOS.
So how can i do that ? and where(in which viewController) should i put the AVPlayer declaration ?
Thanks in advance.
If you are testing in the simulator, the change of views will not continue the audio in the background. If it is not working your device try this:
NSURL *url = [NSURL URLWithString: yourURLHere];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:avAsset];
AVPlayer *audioPlayer = [AVPlayer playerWithPlayerItem:playerItem];
//This enables background music playing
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[audioPlayer play];
Place this code in your viewDidLoad method, before [super viewDidLoad];
I found two links that exaplin some of the issues on this:
Play Music in Background
Play Audio from Internet
If this does not work, I would recommend placing a bounty on the question as it seems your issue's are a little more in depth than a simple solution.
I found the solution, i had to make a singleton class.
The singleton class allow only one object to be used in the entire iOS application by all the ViewControllers.
And i did put all the needed methods like play and pause in the singleton class and i accessed them from all the ViewControllers.
If anybody wants an example, please ask in the comments.

Resume AVPlayer after forwardPlaybackEndTime

I've created an AVPlayer and set the forwardPlaybackEndTime to make a local video stop at a given timestamp. Sure enough, the video stops at the time I've requested. All good.
Now I want the video to continue when triggered by a user action (touching a button, for example). Unfortunately, I can't seem to make that happen without the video restarting from the beginning.
I'll spare you all of the AVPlayer setup code (which is mostly taken from the AV Foundation Programming Guide), but given these variables:
AVPlayer *avPlayer;
AVPlayerItem *playerItem;
I can set the end time like so:
[playerItem setForwardPlaybackEndTime: CMTimeMake(30, 30)];
To attempt the resume, I've tried this:
[playerItem setForwardPlaybackEndTime: CMTimeMake(30, 30)];
[avPlayer setRate: 1.0];
No dice. I've also tried setting the end time and calling play. No luck. I've tried seekToTime to put the playhead at the place where the video stopped in case that would help. It doesn't.
Can someone please explain how to make this work? Thanks!
Try setting the forwardPlaybackEndTime back to the default value, kCMTimeInvalid then continue to play the video.
[playerItem setForwardPlaybackEndTime: kCMTimeInvalid];
[playerItem seekToTime: CMTimeMake(30, 30) toleranceBefore: kCMTimeZero toleranceAfter: kCMTimeZero];
[avPlayer play];

AVPlayer removes background music

I've been using giffycat to decode, store, and play gifs in my app. I am making it so that it can easily load a gif in a UICollectionView's cell, so I have decided for each gif model to have its own AVPlayer. I have noticed that simply by creating an AVPlayer, shown bellow, audio from other apps is killed! Annoying for both the user and the creater!
// Create an AVURLAsset with an NSURL containing the path to the video
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:_mp4] options:nil];
// Create an AVPlayerItem using the asset
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
_player = [AVPlayer playerWithPlayerItem:item]; //if this line is commented out, I hear audio, else audio from Spotify is quickly killed...
Since these videos are just gifs, I am wondering if there is some way to unassign the audio session. I do not know much about this. ples help!
Turns out the answer is pretty easy, after a little googling and documentation reading...
The solution is
// audio session
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryAmbient,
withOptions: AVAudioSessionCategoryOptions.MixWithOthers)
oops, just realized I am posting my question in objC and answer in Swift. Well tough, because that's life sometimes.
AudioSession is a singleton for your entire app to rule how your application mingles with the other sounds of the system and other apps! The default audio session is
playback is enabled, recording is disabled
when user moves silent switch to "silent" your audio is silenced
when user presses sleep/wake button to lock screen or auto-lock period expires, your audio is silenced
when your audio starts, other audio on device (music) is silenced.
CategoryAmbient tells it not to do 4
Nice documentation!
https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/ConfiguringanAudioSession/ConfiguringanAudioSession.html#//apple_ref/doc/uid/TP40007875-CH2-SW1
Set the audioMix property of the AVPlayerItem to nil before creating an AVPlayer from it to remove the audio track from the asset.

Resources