Can't play video file using MPMoviePlayerController - ios

The video file is http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4
I can't play it after copying it into the bundle of an app, then running this:
What's wrong?
-(void)showvideo {
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(mPMoviePlayerLoadStateDidChangeNotification) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
[center addObserver:self selector:#selector(readytoplay) name:MPMoviePlayerReadyForDisplayDidChangeNotification object:nil];
NSBundle* b = NSBundle.mainBundle;
NSString* res = [b resourcePath];
NSString* file;
// file = #"sr.m4v";
// file = #"sample_iPod.m4v";
file = #"big_buck_bunny.mp4";
// file = #"xxx.mp4";
NSString* path = [res stringByAppendingPathComponent:file];
NSFileManager* manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:path]) {
NSLog(#"file exists!");
}
else {
NSLog(#"file does not exist!");
}
NSURL* url = [NSURL URLWithString:path];
NSLog(#"url: %#", url);
self.movieplayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
// self.movieplayer = [MPMoviePlayerController new];
self.movieplayer.movieSourceType = MPMovieSourceTypeFile;
NSLog(#"self.movieplayer: %#, loadState: %d", self.movieplayer, self.movieplayer.loadState);
[self.movieplayer prepareToPlay];
NSLog(#"self.movieplayer: %#, loadState: %d", self.movieplayer, self.movieplayer.loadState);
}
-(void)readytoplay {
NSLog(#"readytoplay");
[self.movieplayer.view setFrame:self.view.bounds]; // player's frame must match parent's
[self.view addSubview:self.movieplayer.view];
NSLog(#"self.movieplayer: %#", self.movieplayer);
self.movieplayer.fullscreen = YES;
NSLog(#"self.movieplayer: %#", self.movieplayer);
[self.movieplayer play];
}
-(void)mPMoviePlayerLoadStateDidChangeNotification {
NSLog(#"mPMoviePlayerLoadStateDidChangeNotification %#, loadState: %d", self.movieplayer, self.movieplayer.loadState);
}
Movieplayer property:
#property (nonatomic, strong) MPMoviePlayerController* movieplayer;

First of all, you can't modify (append, add, delete) application's bundle on runtime. Secondly, NSURL for local files has to be initialised with fileURLWithPath method. Try to correct this issues, and if it doesn't play, try to observe MPMoviePlayerController's loadState changes, and when its loadState is ready to play, then try to play the file. Hope this helps.
EDIT
Sorry, my bad, you are not changing app's bundle on the runtime, just go for Second part. And, you can get the url for the file by calling just [[NSBundle mainBundle] URLForResource:#"file_name" withExtension:#"extension"];

your URL is wrong. Thats y it didnt work out. Use [NSURL fileURLWithPath:path] for url. It should work.

Related

iOS: What is the proper way to implement live audio streaming?

I'm developing an iOS application for a news website, the website has a live audio news channel, i have tried using AVAudioPlayer and did the following:
.h file:
#interface ViewController : UIViewController <AVAudioPlayerDelegate>
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
.m file (viewDidLoad):
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL fileURLWithPath:#"http://198.178.123.23:8662/stream/1/;listen.mp3"];
NSError *error;
_audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
_audioPlayer.delegate = self;
[_audioPlayer prepareToPlay];
}
}
But the application is giving me the following error:
2015-05-25 15:03:12.353 AudioPlayer[2043:421434] Error in audioPlayer: The operation couldn’t be completed. (OSStatus error 2003334207.)
I don't know what's wrong with this code.
Can anyone tell me where's the error in the code ?
Many thanks.
I think there is a better way to play the audio link in the default MPMoviePlayer with audio url. Rest of the things will be managed by default player.
EDIT :
NSURL *audioPath = [NSURL URLWithString:#"Your Audio URL"];
MPMoviePlayerViewController *mpViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:audioPath];
// Remove the movie player view controller from the "playback did finish" notification observers
[[NSNotificationCenter defaultCenter] removeObserver:mpViewController
name:MPMoviePlayerPlaybackDidFinishNotification
object:mpViewController.moviePlayer];
// Register this class as an observer instead
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mpViewController.moviePlayer];
// Set the modal transition style of your choice
mpViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
// Present the movie player view controller
[self presentViewController:mpViewController animated:YES completion:nil];
// Start playback
[mpViewController.moviePlayer prepareToPlay];
[mpViewController.moviePlayer play];
You're getting an error because AVAudioPlayer doesn't support HTTP (meaning that you can't play media from the internet), so what you can do is use AVPlayer it's pretty much similar, here's an example :
- (void)viewDidLoad {
[super viewDidLoad];
NSString *urlAddress = #"http://198.178.123.23:8662/stream/1/;listen.mp3";
urlStream = [NSURL URLWithString:urlAddress];
self.audioPlayer = [AVPlayer playerWithURL:urlStream];
NSError *error;
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
[_audioPlayer prepareForInterfaceBuilder];
}
}
Hope my answer helped you :)

issue playing video in iOS sdk MPMoviePlayerController

I am trying to play video in iPhone, following is the code i have used.
It keep loading but video doesn't play, am i missing anything.
Player is launched but it sonly shows loading and never play the video.
I have also imported MediaPlayer/MediaPlayer.h
-(IBAction)play:(id)sender
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath = [bundle pathForResource:#"test_output" ofType:#"mov"];
NSURL *url = [NSURL URLWithString:
moviePath];
_moviePlayer = [[MPMoviePlayerController alloc]
initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:_moviePlayer];
[_moviePlayer prepareToPlay];
_moviePlayer.controlStyle = MPMovieControlStyleDefault;
_moviePlayer.shouldAutoplay = YES;
[self.view addSubview:_moviePlayer.view];
[_moviePlayer setFullscreen:YES animated:YES];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
if ([player
respondsToSelector:#selector(setFullscreen:animated:)])
{
[player.view removeFromSuperview];
}
}
First, check whether your movie file is added to your project or not.
Second, try creating path with fileURLWithPath. Replace your following code
NSURL *url = [NSURL URLWithString:moviePath];
with
NSURL *url = [NSURL fileURLWithPath:moviePath];
I can't see any code which calls play method of _moviePlayer.moviePlayer.
Try adding following statement to your code.
[_moviePlayer.moviePlayer play];
Add this statement before [self.view addSubview:_moviePlayer.view];
I hope this will work for you
Buddy your code seems to be correct. The problem is definitely with the URL. Double check whether url is correct or not.

Crash when Running MPMoviePlayerController

Ive been battling with a crash on my exercise app for the past couple of days when I try and play an instance of an MPMoviePlayerController in a UIView created in IB.
The rest of the app runs fine, but if any MPMoviePlayer is instantiated, the debugger pauses the app without raising an exception. It's not just this code that causes it. Other methods of instantiating a moviePlayer from other posts or books cause the same result.
Its when I run this code that it drops out to the main:
NSURL *url = exercise.exerciseVideoURL;//path for vid
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:url];
[self.moviePlayerController.view setFrame:self.movieHostingView.bounds];
[self.moviePlayerController prepareToPlay];
[self.moviePlayerController setControlStyle:MPMovieControlStyleNone];
[self.movieHostingView addSubview:self.moviePlayerController.view];
[[self.moviePlayerController view]
setAutoresizingMask:(UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight)];
[[self.moviePlayerController view] setClipsToBounds:YES];
[[self.moviePlayerController view] setFrame:[[self movieHostingView] bounds]];
[self.movieHostingView addSubview:self.moviePlayerController.view];
self.moviePlayerController.repeatMode = MPMovieRepeatModeOne;
I've tried using MPMoviePlayer instantiating code from other posts, binning off the model and just instantiate it with a direct path like in some of the other posts, but it still drops out to main().
Got it! Ive removed "All Exceptions" from the breakpoint tab and its running fine.Why would that cause it to drop out for MPMoviePlayer?!
Anyhow, Thanks to everyone who helped out.
are you reading video from disk (main bundle) or via internet?
First, be always sure that your filepath is correct:
NSString *filepath = [url absoluteString];
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath])
{
NSLog(#"file exists so init player");
}
else
{
NSLog(#"try again!");
}
In my case I always add MPMoviePlayerController after its loaded.
So you can do something like this:
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"demo" ofType:#"mp4"];
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath])
{
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
_moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[_moviePlayerController prepareToPlay];
NSLog(#"frame = %#", NSStringFromCGRect(_moviePlayerController.backgroundView.frame));
[_moviePlayerController.view setBackgroundColor:[UIColor yellowColor]];
[_moviePlayerController.view setFrame:CGRectMake(0, 280, 320, 200)];
//
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieLoadStateDidChangeNotification:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:_moviePlayerController];
}
and then some time later:
- (void)movieLoadStateDidChangeNotification:(NSNotification *)notification
{
[self.view addSubview:_moviePlayerController.view];
}

Detecting Current Item in AVQueuePlayer and Knowing when it Changes?

I currently have an AVQueuePlayer playing a few .aif files in sequence. As it goes through each audio I want to perform an action related to that specific sound (for example changing an imageview's uiimage).
My problem is setting the NSNotification correctly. I've set it to notify me when the queue finished with the last object, but I'm having trouble receiving an a notification for each current item. Here is what I have:
//Setting Up My Queue List
yellowVoice = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/YellowVoice.aif", [[NSBundle mainBundle] resourcePath]]]];
orangeVoice = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/OrangeVoice.aif", [[NSBundle mainBundle] resourcePath]]]];
redVoice = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/RedVoice.aif", [[NSBundle mainBundle] resourcePath]]]];
pinkVoice = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/PinkVoice.aif", [[NSBundle mainBundle] resourcePath]]]];
NSArray *soundEmotions = [NSArray arrayWithObjects:yellowVoice, orangeVoice, redVoice, pinkVoice, nil];
soundQueue = [AVQueuePlayer queuePlayerWithItems:soundEmotions];
// Notify me when queue reaches the end of the last player item
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[soundEmotions lastObject]];
// Notify me when a new player item begins and which one it is
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(currentItemIs:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[soundQueue currentItem]];
[soundQueue play];
I feel like I'm stuck with the name parameter. What should I change it to? And how would I find out the name of the player item that is currently playing, as it switches? Thanks!
//Here is one of the things I want to do with that info
- (void)currentItemIs:(NSNotification *)notification {
if (soundQueue.currentItem ==yellowVoice) {
UIImage * yellowImage = [UIImage imageNamed:#"yellow.png"];
[UIView transitionWithView:self.view
duration:1.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
mainImage.image = yellowImage;
} completion:NULL];
}
if (soundQueue.currentItem ==yellowVoice) {
UIImage * orangeImage = [UIImage imageNamed:#"orange.png"];
[UIView transitionWithView:self.view
duration:1.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
mainImage.image = orangeImage;
} completion:NULL];
}
}
- (void)currentItemIs:(NSNotification *)notification
{
AVPlayerItem *p = [notification object];
if (p ==yellowVoice) {
//rest of the code
}
}
Bhushan's answer is missing the loop to trigger the notification for each item, so:
for (AVPlayerItem *playerItem in queuePlayer.items) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(currentItemIs:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
}

MPMoviePlayerController gives me a black empty view,no video playing

iOS 5.1 ,here is the code:
MPMoviePlayerController *player =
[[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString:#"map.mp4"]];
[player prepareToPlay];
[player.view setFrame: self.view.bounds]; // player's frame must match parent's
[self.view addSubview: player.view];
// ...
[player play];
in fact ,this is just the same as the apple reference say,but when I click the button to use this function,there is just a black Rectangle stay there,no vedio playing ,no sound happening,and no crush,so I want to know how to make this work
Sorry for very late reply. The Solution is kind of wierd. But it helped me keep going while facing the same issue.
MPMovieSourceTypeStreaming is the thing you have missed.
MPMoviePlayerController *player =
[[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString:#"map.mp4"]];
[player prepareToPlay];
[player.view setFrame: self.view.bounds]; // player's frame must match parent's
player.movieSourceType = MPMovieSourceTypeStreaming;
[self.view addSubview: player.view];
// ...
[player play];
You may be sending your
[player play]
message too soon.
Use the following notification observation
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playMovie:) name:MPMoviePlayerLoadStateDidChangeNotification object:player];
To listen for the loadState to change to playable. To check for that update do this :
- (void)playMovie:(NSNotification *)notification {
MPMoviePlayerController *player = notification.object;
if (player.loadState & MPMovieLoadStatePlayable)
{
NSLog(#"Movie is Ready to Play");
[player play];
}
}
The movie should begin playing once it's ready.
Try this below code for play video from your project Resource :
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath = [bundle pathForResource:#"map" ofType:#"mp4"];
NSURL *movieURL = [[NSURL fileURLWithPath:moviePath] retain];
MPMoviePlayerController *player =
[[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[player prepareToPlay];
[player.view setFrame: self.view.bounds]; // player's frame must match parent's
[self.view addSubview: player.view];
// ...
[player play];
Thanks..!
Building on #Dinesh's answer, your URL creation is incorrect. The value of
[NSURL URLWithString:#"map.mp4"]
will be nil since #"map.mp4" is not a valid URL. To create a valid url from the app's bundle do what Dinesh says. To create a remote URL you would do something like
[NSURL URLWithString:#"http://www.jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v"]
The URL should contain all it's parts: protocol, host, path, file.
Cheers, Felipe
Add your movie player controller view on main windows like:
MPMoviePlayerController *player =
[[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString:#"map.mp4"]];
[player prepareToPlay];
[player.view setFrame: self.view.bounds];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.window addSubview: player.view];
[player play];
Hope so it will work!
Your player should be a property of your view controller, something like this:
.h:
#property(nonatomic,weak)MPMoviePlayerController *moviePlayer;
.m:
MPMoviePlayerController *player =
[[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString:#"map.mp4"]];
[player prepareToPlay];
[player.view setFrame: self.view.bounds]; // player's frame must match parent's
//set the player to your property
self.moviePlayer=player;
[self.view addSubview: self.moviePlayer.view];
// ...
[self.moviePlayer play];
Please use MPMoviePlayerViewController Because of MP4 file. When you use MOV then working perfect!!
MPMoviePlayerViewController *moviePlayerViewController;
-(void)PlayVideoController:(NSString*)videoUrl1 {
NSURL *fileURL = [NSURL URLWithString:videoUrl1];
moviePlayerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:fileURL];
// Register for the playback finished notification.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMovieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerViewController.moviePlayer];
//Present
[self presentMoviePlayerViewControllerAnimated:moviePlayerViewController];
// Play the movie!
moviePlayerViewController.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[moviePlayerViewController.moviePlayer play];
}
-(void)myMovieFinishedCallback:(NSNotification*)aNotification {
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerViewController.moviePlayer];
[moviePlayerViewController release], moviePlayerViewController = nil;
}
You might want to cross check video url for blank spaces. Following code works for me.
- (IBAction)btnPlayVideo:(id)sender {
self.strVideoUrl = [self.strVideoUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *fileURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#", self.strVideoUrl]];
NSLog(#"Url to play = %#", self.strVideoUrl);
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayerController];
[self.moviePlayerController.view setFrame:self.view.bounds];
[self.view addSubview:self.moviePlayerController.view];
self.moviePlayerController.shouldAutoplay = YES;
self.moviePlayerController.fullscreen = YES;
self.moviePlayerController.controlStyle=NO;
[self.moviePlayerController prepareToPlay];
self.moviePlayerController.movieSourceType = MPMovieSourceTypeStreaming;
[self.moviePlayerController play];
}
- (void)moviePlaybackComplete:(NSNotification *)notification
{
self.moviePlayerController = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayerController];
[self.moviePlayerController.view removeFromSuperview];
self.closeVideAdProp.hidden = NO;
btnCloseAd.hidden=FALSE;
}

Resources