I have recently started adding videos to ios apps using AVPlayer.But,now I have to get video data in chunks(HLS) rather than getting all data together ,but I am not able to understand the difference between this concept of playing data obtained in chunks or playing the whole data obtained altogether as implemented below .I have tried understanding this thing and looked for examples on internet but got the same thing as already implemented by me.Kindly give your suggestions and guidance that can help me to move forward.Thanks in advance!
-(void)playVideo:(NSURL*)videoURL
{
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:videoURL];
AVPlayer* playVideo = [[AVPlayer alloc] initWithPlayerItem:playerItem];
_playerViewController = [[AVPlayerViewController alloc] init];
_playerViewController.player = playVideo;
_playerViewController.view.frame = self.view.bounds;
[self.view addSubview:_playerViewController.view];
[playVideo play];
}
Read this Document from Apple.
When you init player, it doesn't mean that player is ready to play. You should observe player's status until you get AVPlayerStatusReadyToPlay status.
From your code, you init player and directly start playing video. You should observe status of player by following code.
[player addObserver:self forKeyPath:#"status" options:0 context:&PlayerStatusContext];
Related
I do not have a problem a stream, but I do not know when it is buffering or when the stream has ended. Is there anyway to determine this in Objective-C. I have found solutions for audio and I even tried the AVPlayerItemDidPlayToEndTimeNotification but it does not work. Any suggestions?
NSString *url = liveStream.stream[#"cdn"];
dispatch_async(dispatch_get_main_queue(), ^{
AVPlayerItem *playerItem = [[AVPlayerItem alloc]
initWithURL:[NSURL URLWithString:url]];
[_player replaceCurrentItemWithPlayerItem:playerItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
[_player play];
});
}
-(void)itemDidFinishPlaying:(NSNotification *) notification {
}
In addition to the notification you're using, you should use KVO to observe the rate of the avPlayer, as well as the status of the avplayer's current AVPlayer item. From observing those properties, you can make a state machine of sorts where your player view controller knows what's going on, and can recover from various changes instate. There are various player states that you have to prepare for and recover from based on the properties that you observe.
Here's an answer on how to check for buffering
Here's an example of a complete AVPLayer
And of course, here's apple's documentation on AVPlayer
Here's the documentation on AVPlayerItem
Lastly, here's the link on KVOController. You'll thank me for this later.
I do need to implement iOS application with video files played back in background.
E.g. on first viewController one video should be played back in background instead of some photo or color background.
on second viewController another video should be played back in background instead of some photo or color background.
and so on.
What is the best way to implement this?
* is it better to import those video files in project?
* or is it better to store them in some external place and playback via network?
From the AppStore approval point of view and from the Apple Guidlines point of view - is this case with video correct? Or it's better to avoid video usage in mobile applications?
Thank you in advance.
Found solution with local video files playback via native AVPlayer from AVFoundation
1.Import AVFoundation:
#import <AVFoundation/AVFoundation.h>
2.Use property for player:
#property (nonatomic) AVPlayer *avPlayer;
3.Add video file into "Video" folder and added "Video" into project
4.Initialize the player
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"shutterstock_v885172.mp4" ofType:nil inDirectory:#"Video"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
self.avPlayer = [AVPlayer playerWithURL:fileURL];
self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
AVPlayerLayer *videoLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
videoLayer.frame = self.view.bounds;
videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:videoLayer];
[self.avPlayer play];
5.Subscribe for event - video did play to the end
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.avPlayer currentItem]];
6.Resume video playback to the very start in related method
- (void)itemDidFinishPlaying:(NSNotification *)notification {
AVPlayerItem *player = [notification object];
[player seekToTime:kCMTimeZero];
}
I want to play mp4 video files using MPMoviePlayerController.
Here is the code I am currently using:
NSURL *url = [NSURL URLWithString:
videoLink];
MPMoviePlayerController *controller = [[MPMoviePlayerController alloc ]init];
[controller`enter code here` prepareToPlay];
self.mp = controller; //Save obj reference
Also I am re using same player object because have to load another video file as soon as next or previous clicked on UI.
controller.view.frame = CGRectMake(0, yMargin, self.view.frame.size.width, self.view.frame.size.width*9/16); //Set the size
[self.view addSubview:controller.view];//Show the view
[controller setContentURL:url];
[controller play]; //Start playing
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification object:self.mp ];
Sometimes it's loading video properly but randomly showing an error message as given below.
itemFailedToPlayToEnd: {
kind = 1;
new = 2;
old = 0;
}
If error comes it doesn't load any other video afterwards at least for next 15(approx.) attempts.This behaviour is very random as sometimes it keeps showing the error in log and player doesn't load the video at all.
Has someone else faced this similar issue ? I found many questions posted related to this problem but nothing seems to be working for me.
Other solution i found playing a video using web view but auto play
doesn't work for web view.
I use MPMoviePlayerController to play a list of audio streams from url. I use the following code to init the player
self.player = [[[MPMoviePlayerController alloc] init] autorelease];
self.player.controlStyle = MPMovieControlStyleNone;
and later use the following code to set and reset contentUrl:
self.player.contentURL = url;
[self.player prepareToPlay];
but sometimes, not every time, it fails to play audio, post MPMoviePlayerPlaybackDidFinishNotification directly and gives following userInfo
{
MPMoviePlayerPlaybackDidFinishReasonUserInfoKey = 1;
error = "Error Domain=MediaPlayerErrorDomain Code=-11828 \"Cannot Open\" UserInfo=0xee7bf20 {NSLocalizedDescription=Cannot Open}";
}
anyone knows why?
I would suggest you use AVPlayer instead of MPMoviePlayerController.
I had seen such issues before when streaming audio with MPMoviePlayerController. AVPlayer is the more appropriate one for this task.
I would like to open the iPad movie player from my app to play a video.
The video will already be on the device, and the app is destined to ad-hoc distribution on pre-configured device, thus we can say the video will always be here.
My problem is that I can't figure out how to open the video app! I've searched a lot of things, including UTI, or embedded video, but that doesn't meet my needs.
Is there any way to simply open the player with the specified file ?
Do you need to open the video app per se? Or do you just need to play local video file from your app? In the latter case, you can just use MPMoviePlayerController (or the wrapping MPMoviePlayerViewController for iOS > 3.2).
Something like this works for me.
NSURL * url = [[NSBundle mainBundle] URLForResource:#"yourvideo" withExtension:#"mov"];
player = [[MPMoviePlayerController alloc] initWithContentURL:url];
player.view.frame = self.view.bounds;
player.movieSourceType = MPMovieSourceTypeFile;
[self.view addSubview:player.view];
player.shouldAutoplay = NO;
player.fullscreen = YES;
[player prepareToPlay];