This is not the No video, audio only problem. It's just the opposite.
The problem arises when using iOS 5.0. iPads running 4.3 or lower play the same video files flawlessly.
since iOS 5 changed the way stuff is initialized for MPMoviePlayerControllers, I had to do some SDK based programming in order to get the video to be displayed. Before implementing the snippet I'm showing next, the video and it's controls won't even show up on the screen. The controller would only show a black square with the size and origin of given CGRect frame.
The way I handle it is the following:
The video files are located on the documents folder. So the NSURL has to be initialized as fileURLWithPath. Once that's done, I proceed to initialized the controller with a given frame. Since it wouldn't work otherwise, the view will only add the player once it has changed its loadState. That's achieve by subscribing to a notification. the subscriber selector performs the addition of the controller's view to the parent view on the main thread since the notification could be handled from other threads.
Initializing and adding video to the view:
-(void)addVideo:(NSString*) videoName onRect:(CGRect)rect {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
iPadMagazineAppDelegate *appDelegate = GET_APP_DELEGATE;
NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dirName = [dirArray objectAtIndex:0];
// get directory name for this issue
NSURL *baseURL;
/*
BUGFIX: Video does not work on iOS 5.0
*/
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"5.0")){
baseURL = [[NSURL fileURLWithPath:dirName]URLByAppendingPathComponent:[appDelegate.currentIssue getIssueDirectoryName ]];
}else {
baseURL = [[NSURL URLWithString:dirName] URLByAppendingPathComponent:[appDelegate.currentIssue getIssueDirectoryName]];
}
/* end BUGFIX: Video does not work on iOS 5.0 */
NSURL *videoURL = [baseURL URLByAppendingPathComponent:videoName];
MPMoviePlayerController * movieController= [[MPMoviePlayerController alloc]initWithContentURL:videoURL];
// set frame for player
movieController.view.frame = rect;
// set auto resizing masks
[movieController.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
// don't auto play.
[movieController setShouldAutoplay:NO];
[movieController setUseApplicationAudioSession:YES];
/*
BUGFIX: Video does not work on iOS 5.0
*/
if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(#"5.0")) {
[movieController prepareToPlay];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(loadVideo:) name:MPMoviePlayerLoadStateDidChangeNotification object:movieController];
}else {
[pdfView addSubview:movieController.view];
[pdfView bringSubviewToFront: movieController.view];
}
/* end BUGFIX: Video does not work on iOS 5.0 */
[_moviePlayerViewControllerArray addObject:movieController];
[movieController release];
[pool release];
}
notification handler:
-(void)loadVideo:(NSNotification*)notification {
for (MPMoviePlayerController *movieController in _moviePlayerViewControllerArray) {
if (movieController.loadState != MPMovieLoadStateUnknown) {
[pdfView performSelectorOnMainThread:#selector(addSubview:) withObject:movieController.view waitUntilDone:YES];
[pdfView performSelectorOnMainThread:#selector(bringSubviewToFront:) withObject:movieController.view waitUntilDone:YES];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:movieController];
}
}
}
Thank you for reading this huge question. I appreciate your answers.
cheers.
Try this:
Set MPMoviePlayerController's property "useApplicationAudioSession" to "NO".
Apparently there's a bug, but it's not related to the MPMoviePlayerController, but to iOS 5 itself.
My iPad was muted from the switch but still played audio from iPod app anyway so I didn't realized that it was that way, so MPMoviePlayerController was fine, but part of the OS did not notice that the iPad was muted.
I've filed the corresponding bug on Apple's bug tracker. Bug ID# 10368531.
I Apologize if I've wasted your time.
UPDATE: Got feedback from apple for the bug. It's expected behavior. :\
Related
After the release of iOS 13, there was some exception in one of our video playback interfaces.
This interface is to play video using MPMoviePlayerController.
In some cases, videos that would only be played once will now automatically loop.
At the same time, the MPMoviePlayerPlaybackDidFinishNotification notification is also not received.
From the feedback of users, this problem will only appear on iOS13 devices.
After testing, I found that only one iPhone11 in all iOS13 devices will have this problem, and other iOS13 devices (including another iPhone11) have no such problem.
When the problem occurred, I printed the value of the repeatMode property and found that it is still 0.
Later I tried to manually set the repeatMode to MPMovieRepeatModeNone and found that this problem still occurs.
Some additional information:
1) For some reason, I am still using Xcode10.3 (Base SDK: iOS12.4) to compile the project, so using MPMoviePlayerController does not crash directly.
2) The problematic device is the partner's test machine, so I can only remotely instruct them to test, there is no way to debug locally.
Here is the code I used to test:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:filePath];
self.playerController = [[MPMoviePlayerController alloc] init];
[self.playerController setScalingMode:MPMovieScalingModeAspectFit];
[self.playerController.backgroundView setBackgroundColor:[UIColor clearColor]];
self.playerController.movieSourceType = MPMovieSourceTypeFile;
[self.playerController setControlStyle:MPMovieControlStyleNone];
[self.playerController.view setFrame:self.view.bounds];
self.playerController.view.userInteractionEnabled = YES;
[self.view addSubview:self.playerController.view];
self.playerController.contentURL = url;
[self.playerController prepareToPlay];
[self.playerController play];
I'm developing a iOS app using objective-c. When the application is launched a background music is played. The background music should continue playing when the user clicks help button. Also when the user goes back to the main screen from the help screen the background music should be continuously playing.
For me a new background music is getting played along with the old background music when I navigate from help to main menu. So, I am hearing two background music now.
Could anyone help me in solving this issue?
Regards,
Bharathi.
Your problem could be solved if you retained a reference to your audio player in your UIApplicationDelegate (or some other singleton that's kept around).
//in the .h
#property (nonatomic, strong) AVAudioPlayer *player;
//in the .m
- (void) playMusic
{
if (self.player == nil) {
NSString *path = [NSString stringWithFormat:#"%#/music.mp3", [[NSBundle mainBundle] resourcePath]];
NSURL *soundUrl = [NSURL fileURLWithPath:path];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
}
if (!self.player.isPlaying) {
[self.player play];
}
}
That way you can call it wherever you need with a:
[(MyAppDelegate*)[UIApplication sharedApplication].delegate playMusic];
Though it might be to your advantage to keep around a SoundsManager class as a singleton in order to handle all the sounds that you'll need to track if you're going to need more than just this one.
I am little bit confused about the behaviour.
What I want to do is,
I am having two different application.
One is made by me and other is by a guy who left the company & now I have to complete his projects.
But the task to be done in both project is same.
I have to show 5 sec video when I open the app every time.
Like Some branding video. (Done in angry birds app)
I checked all the links on SO, but didn't helped any one.
My senior who left the company, he have used Main.storyboard for navigation each screen.
and I am not that much good in using storyboard.
In my app, I created navigation programatically.
When my splash screen disappears,
I show dashboard.
But before showing dashboard, I have to show the video every time.
So what I did,
I created a view controller only for Video named VideoViewController,
and call that view controller from ViewDidLoad of dashboardView.
and when my video finished,
then by using NSNotificationCenter I removed the VideoViewController.
When I Nslog the url path, its printing correct, but My app crashes after that.
I checked it by applying ExceptionalBreakpoints, but didn't helped.
Here is my code to launch video in ViewDidLoad of VideoViewController
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"video" ofType:#"mp4"]];
NSLog(#"video path :- %#",url);
playercontroller = [[MPMoviePlayerController alloc] init];
[playercontroller setContentURL:url];
[playercontroller.view setFrame:CGRectMake (0, 0, 320, 460)];
[self.view addSubview:playercontroller.view];
[playercontroller play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:playercontroller];
and I am pushing VideoViewController from dashboard's
-(void)viewDidAppear:(BOOL)animated
method.
As I am doing any thing wrong.
As My url is getting Nslg well, so no doubt of loading video.
Please guide me for the same.
also guide me to achieve same task using storyboard.
Thanks in advance.
you shouldn't hardcode set the frame like that though..
Assuming 'self' is a ViewController (which has been properly addChildViewController'ed all the way from the RootViewController), try the next thing:
NSString *path = [[NSBundle mainBundle] pathForResource:videoFileName ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:path];
MPMoviePlayerViewController *videoController = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
[self presentMoviePlayerViewControllerAnimated:videoController];
[videoController.moviePlayer play];
I am trying to play a video file (m4v) from resource folder of my app (i.e local video). but I am not able to play the video. I referred apple's sample project for the MPMoviePlayer.
Also when i am giving background color to my movieplayercontroller object its appearing as its behind some black view and the black view ahead is showing that something is loading for few seconds but nothing get loaded and it results in black screen only.
Can someone help me out with it. please tell me what i am doing wrong.
Also, i have taken screenshot of the screen with problem so that you all can understand what i am trying to say but i dont know how to post it here. :(
NSString *urlString = [[NSBundle mainBundle] pathForResource:#"Movie" ofType:#"m4v"];
NSURL *urlObj = [NSURL fileURLWithPath:urlString];
UIGraphicsBeginImageContext(CGSizeMake(1,1));
MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:urlObj];
UIGraphicsEndImageContext();
[player.view setBounds:self.view.bounds];
// when playing from server source type shoud be MPMovieSourceTypeStreaming
[player.moviePlayer setMovieSourceType:MPMovieSourceTypeStreaming]; // I was missing this line therefore video was not playing
[player.moviePlayer setScalingMode:MPMovieScalingModeAspectFill];
[self.view addSubview:player.view];
[player.moviePlayer play];
I just want to load a video file which is in the main bundle, this seems pretty simple but for some reason I keep getting an error of the MPMoviePlayerController, I have the following code.
- (void)viewDidLoad{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"ipad2" ofType:#"mp4"];
self.myPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:path]];
[self.myPlayer prepareToPlay];
self.myPlayer.movieSourceType = MPMovieSourceTypeFile;
[self.myPlayer.view setFrame:self.view.bounds];
[self.view addSubview:self.myPlayer.view];
[self.myPlayer play];
}
I only get a black screen and the following output:
2013-01-09 13:38:15.686 myVideoApp[1789:907] [MPAVController] Autoplay: Likely to keep up or full buffer: 0
2013-01-09 13:38:15.690 myVideoApp[1789:907] [MPAVController] Autoplay: Skipping autoplay, not enough buffered to keep up.
I also tried adding these notification for playing but is never sent:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(playVideo:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.myPlayer ];
And when I print self.myPlayer.loadState I get 0which is undefined loadState.
These is a simple viewController with any other method, and I have these declaration on the .h file:
#property (nonatomic, strong) MPMoviePlayerController *myPlayer;
I`m running on iOS 6, and these happens both in device and simulator
NSString *path = [[NSBundle mainBundle] pathForResource:#"ipad2" ofType:#"mp4"];
Have you checked in the debugger that path is not nil?
self.myPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:path]];
That's the wrong way to create a URL from a file path. Use +[NSURL fileURLWithPath:] instead.
I also using the MPMoviePlayerViewController to live video on my app and getting same above list errors.And I found MPMoviePlayer not support larger data to show video but if you used smaller data of video is working fine its not give any error. In fact is not problem of prepare to play and play property of movie player.
If you need to show larger data then used webview on your app.