video plays but no picture - just sound? - iphone

Edit: if you come across this and want to know how I eventually solved it I gave up on that code below eventually and did this:
-(void)playMovieAtURL:(NSURL*)theURL{
mediaPlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:theURL];
[self presentMoviePlayerViewControllerAnimated:mediaPlayer];
mediaPlayer.view.backgroundColor = [UIColor blackColor];
}
Original post:
This is my code - I took it off the apple site so shouldn't be a problem.
It runs in a UITableViewController on the didSelectRowAtIndexPath method.
When you select the row the video starts playing - the sound outputs at least - but there's no picture. Any idea why this is? I have included the framework.
The video is one off the apple website (a facetime video) that I used for testing.
-(void)playMovieAtURL:(NSURL*)theURL{
MPMoviePlayerController* theMovie =
[[MPMoviePlayerController alloc] initWithContentURL: theURL];
theMovie.scalingMode = MPMovieScalingModeAspectFill;
theMovie.controlStyle = MPMovieControlStyleNone;
// Register for the playback finished notification
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(myMovieFinishedCallback:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: theMovie];
// Movie playback is asynchronous, so this method returns immediately.
[theMovie play];
}

The behaviour of MPMoviePlayerController changed in OS 3.2 - you need to explicitly add the movie player's view to your view hierarchy now - using something like:
[aView addSubview:moviePlayerController.view];
moviePlayerController.view.frame = aView.frame;
Alternatively you can use an MPMoviePlayerViewController (new in 3.2) to manage the view.
If you're targetting both pre- and post-3.2 devices (e.g. iOS 3.1 and 4.0) then you'll need some conditional code to determine the OS the code is running on and handle accordingly. I've used this in previous projects:
if ([moviePlayerController respondsToSelector:#selector(setFullscreen:animated:)]) {
// Running on OS 3.2 or above
// Code to add to a view here...
}

Related

iPhone app:MpMoviePlayer not playing movie in iPad with ios5

I have created my iPhone app in Xcode 4 with base SDK 4.3
In my iPhone app I have used MPMovieplayercontroller and using that I am playing Video
It is playing my video file in my iPod Touch with IOS 4.3 but if I install same project in my iPad with iOS 5, it is showing black screen only but not playing video.
what could be wrong?
Here is the code
in .h file
MPMoviePlayerController *moviePlayer;
in .m file
-(void)playVideo{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"testbild1" ofType:#"m4v"]];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
UIView *testview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[testview addSubview:moviePlayer.view];
[self.view addSubview:testview];
}
- (void)moviePlaybackComplete:(NSNotification *)notification
{
MPMoviePlayerController *moviePlayerController = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
[moviePlayerController.view removeFromSuperview];
}
It doesn't look like you're setting autoplay
shouldAutoplay
A Boolean that indicates whether a movie should begin playback automatically.
#property (nonatomic) BOOL shouldAutoplay
So like:
moviePlayer.shouldAutoplay = true;
You should also be probably calling prepareToPlay and play from the MPMediaPlayback protocol that MPMoviePlayerController implements
Old Post (should have been a comment):
What version iOS? iOs 5.1 beta just came out and alters how MPMoviePlayerController works.
You can get details on Apple's iOS beta site but I can't print them here YAY EULA.
EDIT
Now that the OS is public, here's the relevant documentation (registration -- you might have to pay the $100 as well, I forget...)
iOS 5.1 Release Notes (Search for prepareToPlay on that page -- no deep linking)
MPMoviePlayerController class documentation

Iphone : Video playing at startup doesn't quit

i made a video playing when my app loads however it doen't quit after playing even if you prees "Done". What am i doing wrong?
- (void)viewDidLoad {
NSBundle *bundle=[NSBundle mainBundle];
NSString *moviePath = [bundle pathForResource:#"Video Logo Final" ofType:#"mp4"];
NSURL *movieURL=[[NSURL fileURLWithPath:moviePath] retain];
MPMoviePlayerController *theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
theMovie.scalingMode = MPMovieScalingModeAspectFill;
theMovie.view.frame = CGRectMake(0.0, 0.0, 320.0, 480.0);
[self.view addSubview:theMovie.view];
[theMovie play];
[super viewDidLoad]; }
Also, i made a try to put the same code in "application didFinishLaunchingWithOptions" but i get a warning at "[self.view addSubview:theMovie.view];"
Ay ideas about that?
p.s. As you probably guessed i am very new to programming, any help would be really appreciated...
Basically you need to register for a notification.
The way I do it is:
// Register for the playback finished notification
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(myMovieFinishedCallback:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: theMovie];
Change the parameters to fit however it should in your app.
Here's the documentation for the MPMoviePlayerPlaybackDidFinishNotification.
Also, if it's not "quitting" after playing (even when hitting the "Done" button), it sounds like you need to remove the theMovie MPMoviePlayerController and associated view from the view you originally added it to.

MPMoviePlayerController plays after canceling in 3.1.2

I have encountered a problem with the MPMoviePlayerController in 3.1.2.
If I cancel the player while it is still loading, the player closes. However, the video starts playing a few moments later in the background. The only ways to stop it are to play another video or close the app. This seems to work fine in 3.2+.
Here's what I'm doing:
- (void)loadMoviePlayer
{
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
if ([NSClassFromString(#"MPMoviePlayerController") instancesRespondToSelector:#selector(view)])
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
// running iOS 3.2 or better
MPMoviePlayerViewController *moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:#"http://www.mysite.com/myvideo.m3u8"]];
[moviePlayer.view setBackgroundColor:[UIColor blackColor]];
[moviePlayer.moviePlayer setControlStyle:MPMovieControlStyleFullscreen];
// [moviePlayer.moviePlayer setControlStyle:MPMovieControlStyleNone];
[self presentMoviePlayerViewControllerAnimated:moviePlayer];
[moviePlayer.moviePlayer prepareToPlay];
[moviePlayer.moviePlayer play];
#endif
}
else
{
MPMoviePlayerController *mMPPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:#"http://www.mysite.com/myvideo.m3u8"]];
mMPPlayer.scalingMode=MPMovieScalingModeFill;
mMPPlayer.backgroundColor=[UIColor blackColor];
[mMPPlayer play];
}
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
// Remove observer
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
I added moviePlayBackDidFinish this morning. It gets called when I hit cancel, but dismissModalViewControllerAnimated doesn't seem to do anything. I also tried removeFromSuperView, but my player will not respond.
So, how can I make sure the player does not play after hitting "cancel"?
Thanks in advance.
You may have come across an old bug in MPMoviePlayerController. Back in the days, we actually had to play an almost empty (black, silence) M4V after playing proper content to be sure the player does not attempt to continue playback in the background when stopping at certain stages. That bug manifests in audible sound but no picture of the aborted/stopped video.
There are however a few more things worth trying when stopping (assuming your instance of MPMoviePlayerController is called moviePlayer);
set the current playback position to the complete movie duration moviePlayer.currentPlaybackTime = moviePlayer.duration;
send another stop within your notification handler [moviePlayer stop];
In my case, I found that setting the following line would eventually stop the movie player from playing:
moviePlayer.contentURL = nil;
(with moviePlayer your instance of MPMoviePlayerController).

Writing an app to stream video to iPhone

I'm interested in creating an iPhone app that can stream video from a central server, YouTube style. I was wondering if anyone has ever tried to do this before, what is the path of least resistant, existing APIs, etc? I really know nothing about how this is generally done. Would I be working with sockets? Just looking for some direction here. Thanks!
If you have the streaming server up and ready, it is quite easy to implement a video controller that pops up youtube-style.
NSString *videoURLString = #"http://path-to-iphone-compliant-video-stream";
NSURL *videoURL = [NSURL URLWithString:videoURLString];
MPMoviePlayerController moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
[moviePlayer prepareToPlay];
[moviePlayer play];
[self.view addSubview:moviePlayer.view];
You need to handle the controller that display the video player's view (which is self in this case).
In iOS 3.2+ MPMoviePlayerViewController make it even easier:
NSString *videoURLString = #"http://path-to-iphone-compliant-video-stream";
NSURL *videoURL = [NSURL URLWithString:videoURLString];
MPMoviePlayerViewController *moviePlayerView = [[[MPMoviePlayerViewController alloc] initWithContentURL:videoURL] autorelease];
[self presentMoviePlayerViewControllerAnimated:moviePlayerView];
presentMoviePlayerViewControllerAnimated is a MediaPlayer's additional method to FWViewController that you will find in iOS 3.2+ and it takes care of creating a view controller and pushing it on the stack, animating it with a slide-from-bottom animation, as in youtube.app.
Apple has a detailed article about setting up server side for media streaming:
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/Introduction/Introduction.html
and Best Practices Note:
https://developer.apple.com/library/content/technotes/tn2224/_index.html
Not only it contains info about streaming service architecture and tools used to build it but also has some requirements to such kind of service that must be fulfilled and references to live test streams.
Use this code to use low memory. On streaming video....
-(IBAction)playMovie:(NSURL *) theURL
{
NSURL *fileURL = theURL;
MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
[self.view addSubview:moviePlayerController.view];
moviePlayerController.useApplicationAudioSession = NO;
moviePlayerController.fullscreen = YES;
[moviePlayerController play];
}
- (void)moviePlaybackComplete:(NSNotification *)notification
{
MPMoviePlayerController *moviePlayerController = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayerController];
[moviePlayerController.view removeFromSuperview];
[moviePlayerController release];
}
QuickTime videos already stream to the phone. The path of least resistance would be to use the media player controller and point it to a streaming media file on a streaming server.
While the existing answers are good, if you need to use non HTTP streams (mms or rtmp for example) or non Apple supported audio / video codecs, things get a bit more complicated.
I'm not an expert myself, but I've been using this VideoStreaming SDK to solve those problems, and it makes customizing the client much easier (background streaming, pausing streams, etc). Might be worth a look if you have those requirements as well.
2018 answer You can use AVPlayerViewController since MPMoviePlayerController is deprecated since iOS 9
NSURL *url = [NSURL URLWithString:videoUrl];
_playerViewController = [[AVPlayerViewController alloc] init];
_playerViewController.player = [AVPlayer playerWithURL:url];
_playerViewController.player.volume = 1;
_playerViewController.showsPlaybackControls = YES;
_playerViewController.view.frame = CGRectMake(....);
[self.view addSubview:_playerViewController.view];

Overlay View Problem When Playing Two Different Movies in Sequence

I'm trying to play two videos using the MPMoviePlayerController class and allow the user to switch between the two videos by swiping their finger across the screen. Everything works great for the first movie. The overlay view correctly detects the swipe and starts the next movie playing.
Unfortunately things don't work so well with the second movie. I'm not sure what's happening, but the overlay view does not actually seem to be on top of the movie player and is certainly not responding to touch events. In fact, double tapping the screen while the second movie is playing zooms the movie in and out, so touches seem to be going to the MPMoviePlayerController.
I've tried a number of different approaches here, but none of them work. Here is the current version of the code:
- (void)allocateMoviePlayerForCurrentVideo
{
// Create a movie player for the first video in the playlist
NSURL *url = [videoURLs objectAtIndex:nowPlayingVideoIndex];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
moviePlayer.movieControlMode = MPMovieControlModeHidden;
moviePlayer.backgroundColor = [UIColor blackColor];
// Register for the movie preload complete notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePreloadComplete:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:nil];
// Register for the playback did finish notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieDidFinishPlaying:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
}
The code which handles the MPMoviePlayerContentPreloadDidFinishNotification starts the movie playing and adds the overlay view:
- (void)moviePreloadComplete:(NSNotification *)notification
{
// Remove this object from observing the preload complete notification
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerContentPreloadDidFinishNotification
object:nil];
// Start playing the current movie
[moviePlayer play];
// Add the overlay view to the movie player
UIWindow *moviePlayerWindow= [[[UIApplication sharedApplication] windows] objectAtIndex:1];
overlayView = [[GGDMovieOverlayView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
overlayView.backgroundColor = [UIColor clearColor];
[moviePlayerWindow addSubview:overlayView];
[moviePlayerWindow bringSubviewToFront:overlayView];
// Register for swipe notifications from the overlay view
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleMoviePlayerSwipeNotification:)
name:GGDMoviePlayerSwipeNotification
object:nil];
}
And finally, here's the routine which handles the swipe notification:
- (void)handleMoviePlayerSwipeNotification:(NSNotification *)notification
{
// Stop the current movie player and release it
[moviePlayer stop];
[moviePlayer release];
moviePlayer = nil;
// Remove the overlay view from its superview
[overlayView removeFromSuperview];
// Advance to the next movie, treating the array of video URLs as a circular array
if ( ++nowPlayingVideoIndex == [videoURLs count] ) {
nowPlayingVideoIndex = 0;
}
[self allocateMoviePlayerForCurrentVideo];
}
I fear there's something obvious I'm missing, but this has been driving me crazy for a while now. I very much appreciate any help!
Thanks,
Adam
I just went through this myself and I can explain the issue and a slightly better workaround.
The problem with running the next movie in sequence is that the notification that you get when the movie has finished playing occurs before the current movie player window has been removed from the view. This is an issue because (as per the Apple example) the only way to get the movie player window is to grab the top window on the stack (or the key window). But if you try to use this technique immediately you'll get the old movie player window that is fading out, not the new one that is going to start. (As an aside - frankly, the Apple example is an illustration that there really isn't a proper way to get the movie window at all.. their example is terrible and is probably a race condition to begin with unless somehow the play method blocks until the window is actually on the stack).
Anyway, rather than an arbitrary delay, what I did is to tag the player window at the time that it is first created e.g.
UIWindow *moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
moviePlayerWindow.tag = MY_MOVIE_WINDOW_TAG; // this is just an int
and then in the moviePlaybackDidFinish method I call a waitForMovieWindowToExit method that looks for that tagged window. If it's still there then I use a timer to check again in 0.1 seconds. When it finally disappears I play the next sequence.
So, it's still a mess and still using a timer, but at least you are guaranteed to play the next movie within 0.1 second (or whatever) of the next possible time and it won't break if the system is a little slow, etc.
If anyone wants more code I can post it.
Fixed by using a NSTimer to add the overlay view after a delay to make sure the movie has started playing.
Thanks,
Adam