iOS AVPlayer showing screen with a cross line on Play icon - ios

Screen Shot of AVPlayer error
Below is the code snippet, url is the the video url. This error occurs randomly.
I'm unable to trace what is the issue. Also the video is stored in cloud and video buggers to play on the AVPlayer. Is anything missing in the below code.
+ (void)presentVideoForURL:(NSURL *)URL parentViewController:(UIViewController *)parentViewController {
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *setCategoryError;
if (![audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError]) {
Error(#"setCategoryError %#", setCategoryError.localizedDescription);
}
NSError *activationError;
if (![audioSession setActive:YES error:&activationError]) {
Error(#"activationError: %#", activationError.localizedDescription);
}
AVPlayer *player = [[AVPlayer alloc] initWithURL:URL];
AVPlayerViewController *playerController = [[AVPlayerViewController alloc] init];
playerController.player = player;
[parentViewController presentViewController:playerController animated:YES completion:^{
[player play];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackDidFinish:) name:AVPlayerItemDidPlayToEndTimeNotification object:player.currentItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackDidFinish:) name:AVPlayerItemFailedToPlayToEndTimeNotification object:player.currentItem];
}];
}

Check the following 2 scenarios.
1) Check whether the url is correct or not.
2) If your network is slow and AVPlayer is not getting adequate data into it's buffer,it stops loading and shows a UI like you mentioned (A cross bar in play button).So try using high sped network.
If this is the issue,you can restart the player using the playback stall notification.
I had the 2nd issue and I fixed the same like this.

Related

AVAudioPlayer play issue with two sounds as echo

I have a separate View Controller that holds some Audio Message (URL with mp3 files). Here's the code I use to start playing a message:
- (void)playAudioMsg
{
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategorySoloAmbient error: nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://blahblahblah.mp3"]];
NSData *data = [NSData dataWithContentsOfURL:URL];
audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
audioPlayer.numberOfLoops = 0;
audioPlayer.delegate=self;
[audioPlayer play];
}
The first time I open this view controller and click on a message to play, it plays just fine.
Then I dismiss a view controller.
Then I open it again and click on the same audio message. And what happens it's like two separate AVAudioPlayers got created - one of which starts playing audio right away and another is with a one-second delay (it sounds like the first message plays with echo.
Most interesting is when I dismiss a view controller then one message stops playing and another one keeps playing in the background even though when dismissing a view controller, I call [audioPlayer stop].
Can anyone help me with this, please?
I got the solution.
The problem comes from the fact that when I call -(void) playAudioMsg {...} I do it using this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playAudioMsg) name:#"playAudioMsg" object:nil];
... which is declared inside - (void) viewDidLoad {...}. But then I totally forgot to remove that observer when leaving the ViewController:
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"playAudioMsg" object:nil];
}
Without removing the observer and then coming back to the same page, it sets duplicate for the same observer, so the method playAudioMsg gets called twice.

ios AVPlayer failed to stream remote video

I have a AVPlayer that plays video from remote url.
Here is my code:
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:videoUrl];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
self.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = playerView.bounds;
[playerView.layer addSublayer:playerLayer];
[self.player play];
When I start to stream I have only less then a second video chunck and then downloading stops and nothing happens.
MPMoviePlayerController and browser plays this video as usual.
I also doubt, that it might be effect of cropping video (because videos without cropping works fine). Here is the guide I use to crod video http://www.one-dreamer.com/cropping-video-square-like-vine-instagram-xcode/
Also clean app with same setup can't play video.
Any ideas? thanks!
Use the AVPlayerItemPlaybackStalledNotification
[[NSNotificationCenter defaultCenter] addObserverForName:AVPlayerItemPlaybackStalledNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[weakself performBlockOnMainQueueAfterDelay:1.5 block:^{
[weakself.player play];
}];
}];

AVPlayer stops playing when screen is unlocked (but works when locked)

I am trying to have my AVPlayer play audio in the background, even when the screen is locked. Right now, it does play when the screen is locked, but as soon as it is unlocked, it stops.
In the application delegate I have
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
and I play the sound by doing
AVPlayer *player = [[AVPlayer alloc]initWithURL:self.mp3URL];
_audioPlayer = player;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_audioPlayer currentItem]];
[_audioPlayer play];
I also have the required background modes set to "App plays audio" in the info.plist. Any ideas?
There's nothing i see as a reason in the code you posted. perhaps you are reactivating the audio session causing it to stop when the view shows? The error is not in the code you posted.

MPMoviePlayerController interrupts AirPlay iPod audio, but it works fine on the device

I'm using MPMoviePlayerController to play a video clip that loops. In the app delegate, I set my AVAudioSession's category to AVAudioSessionCategoryAmbient so that my video clip doesn't interrupt iPod audio.
This works great when playing iPod audio on the device, but when using AirPlay, the audio is briefly interrupted every time my looping video starts over, which is pretty frequent (and annoying).
In AppDelegate.m:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:#"AVAudioSessionCategoryAmbient" error:nil];
In my video view controller:
self.videoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
self.videoPlayer.useApplicationAudioSession = YES;
self.videoPlayer.controlStyle = MPMovieControlStyleNone;
self.videoPlayer.repeatMode = MPMovieRepeatModeOne;
I've scoured the net and can't seem to find answers. Any advice would be great. Thanks!
Problem solved! I just had to use AVPlayer instead of MPMoviePlayerController.
self.avPlayer = [AVPlayer playerWithURL:url];
self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
self.avPlayerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:self.avPlayerLayer];
[self.avPlayer play];
And to make it loop:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieDidFinish:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[self.avPlayer currentItem]];
...
- (void)movieDidFinish:(NSNotification *)notification {
[self.avPlayer seekToTime:kCMTimeZero];
}

MPMoviePlayerController playing audio stream in the background

I am running into trouble with playing an audio stream when the application enters background.
I use the code to start the stream:
NSURL *mediaURL = [NSURL URLWithString:#"http://url.to.my.stream"];
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] initWithContentURL:mediaURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp setMovieSourceType:MPMovieSourceTypeStreaming];
[mp setFullscreen:YES];
[self.view addSubview:[mp view]];
[mp prepareToPlay];
[mp play];
It works perfect. But allthough I set the flag 'App plays audio' in the property list when the app enters background the stream stops playing.
How do I make my application play the audio stream in the background?
Best regards and thanks a lot for help!
I didn't tried it myself but this looks promising: iOS Multitasking: Background Audio
Once the project has been created go to APP-Info.plist and add
UIBackgroundModes as a new row. It should then create the array.
Open the array and to the right of Item 0 set it to audio.
EDIT
Is your AVAudioSession set up properly?
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
This code worked for me, first you must to give your app permissions to keep playing music in the background (In your .plis), after that go to the wished class and implement this code, first the imports and the the method to play the music.
#import <MediaPlayer/MPNowPlayingInfoCenter.h>
#import <MediaPlayer/MPMediaItem.h>
#import <AVFoundation/AVFoundation.h>
---- o ----
-(void) playMusic{
[[AVAudioSession sharedInstance] setDelegate: self];
NSError *myErr;
// Initialize the AVAudioSession here.
if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&myErr]) {
// Handle the error here.
NSLog(#"Audio Session error %#, %#", myErr, [myErr userInfo]);
}else{
// Since there were no errors initializing the session, we'll allow begin receiving remote control events
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
//initialize our audio player
audioPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:#"http://www.cocoanetics.com/files/Cocoanetics_031.mp3"]];
[audioPlayer setShouldAutoplay:NO];
[audioPlayer setControlStyle: MPMovieControlStyleEmbedded];
audioPlayer.view.hidden = YES;
[audioPlayer prepareToPlay];
[audioPlayer play];
}//end playmusic

Resources