I am researching video streaming for an iPhone application that I may have to write in the near future. The application does a whole lot other than stream video, but video aspect is the part that I have no experience with.
Anyone know of any good articles on writing streaming video apps?
Google seems to inundate me with links that have everything not to do what I seek.
Thanks,
m
Apple provide good documentation on the media framework i ntheir docs.
Search for MPMoviePlayerController. The following sample code plays a movie from a URL. (disclaimer, this code lifted from Apple).
-(void)playMovieAtURL:(NSURL*)theURL
{
MPMoviePlayerController* theMovie=[[MPMoviePlayerController alloc] initWithContentURL:theURL];
theMovie.scalingMode=MPMovieScalingModeAspectFill;
theMovie.userCanShowTransportControls=NO;
// 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];
}
// When the movie is done,release the controller.
-(void)myMovieFinishedCallback:(NSNotification*)aNotification
{
MPMoviePlayerController* theMovie=[aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
// Release the movie instance created in playMovieAtURL
[theMovie release];
}
I am looking at this issue as well. I would like to embed a video in an iPad app, something like how the Associated Press iPad application handles videos.
Apparently you can do this type of embedded video in OS 3.2 and later. Apple's documentation for MPMoviePlayerController describes how this can be done:
http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/MPMoviePlayerController/MPMoviePlayerController.html
Related
I am wondering if it would be possible to insert your own audio once the ios media library has taken over in an app?
Example: Playing a piece of audio after every song that says the number of songs you've listened to that day.
I know that because its a framework there is only so many things they let you do.
This should be doable. To start, you can add your class as an observer of the MPMusicPlayerControllerNowPlayingItemDidChangeNotification to be informed when the song in the iPod library changes. From there, you can tell the iPod library to pause, play your track, and then resume music playback afterwards.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(someSel:) name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification object:nil];
[[MPMusicPlayerController iPodMusicPlayer] pause];
// play your sound
[[MPMusicPlayerController iPodMusicPlayer] play];
I have an app that streams video from the net and plays it using an MPMoviePlayerController object for playback on the device or via AirPlay.
The app supports background operation and has the 'audio' option listed within the required UIBackgroundModes key in its plist file.
When playing over AirPlay, the app can successfully be pushed to the background and the video continues to play properly. So far, so good.
According to the Apple documentation:
Including the audio key tells the system frameworks that they should
continue playing and make the necessary callbacks to the app at
appropriate intervals. If the app does not include this key, any audio
being played by the app stops when the app moves to the background.
However, these callbacks are not being made.
The app uses two types of callback: those associated with notifications MPMoviePlayerController and AVPlayer send during playback together with timer based callbacks that monitor the playback position and performance stats for monitoring purposes.
Looking at Apple's notes, I would certainly expect to receive the first type of callback so that the app can respond to MPMoviePlayerPlaybackStateDidChangeNotification, MPMoviePlayerPlaybackDidFinishNotification and MPMoviePlayerLoadStateDidChangeNotification, but this doesn't happen.
Does anyone know if it is possible to receive these during background AirPlay playback and, if so, how was this achieved?
**Please note: the app works correctly when running in the foreground and receives the notifications fine. It is only when pushed to the background and playing over AirPlay that the notifications are not received.
Likewise, the video plays over AirPlay in the background properly. It is only the notifications which are not received**
I had this issue and have fixed it though it was a few months back. I could send you my entire class for movie playback if this doesn't work. Note it is using the navigation controller model.
NOTE: This is tested on iPad 2 not on the iPhone.
I show my VC like this:
- (IBAction)playMovie:(id)sender {
MovieVC* movController = [[MovieVC alloc] initWithID:2];
movController.view.backgroundColor = [UIColor blackColor];
AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
[appDel.navigationController pushViewController:movController animated:NO];
[movController release];
}
Then in my MovieVC view controller class i set up the video playback like this:
- (void)initMoviePlayer {
mMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[self getMovieURL]];
mMoviePlayer.allowsAirPlay = YES;
mMoviePlayer.view.frame = [self.view bounds];
mMoviePlayer.view.backgroundColor = [UIColor clearColor];
mMoviePlayer.shouldAutoplay = YES;
mMoviePlayer.fullscreen = YES;
mMoviePlayer.scalingMode = MPMovieScalingModeAspectFit;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePreloadDidFinish:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:mMoviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
}
This fixed it for me, if it doesn't fix comment and ill edit with the entire class file.
In one of my projects I did what you did, and it worked for me.
Two differences in my project :
I am not streaming via airPlay (device playback only),
I am just playing audio files.
My step-by-step :
Add the audio option to UIBackgroundModes in the plist file,
Register to the NotificationCenter for MPMoviePlayerPlaybackDidFinishNotification and MPMoviePlayerPlaybackStateDidChangeNotification with the following code :
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(playbackStateChanged:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:moviePlayer];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(playbackEnded:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
It works like a charm.
For completeness, I ought to add that at present I believe there is no solution to this problem.
I've discussed it directly with Apple via tech support and there was no practical work-around available.
This functionality was needed to allow the app to record stats about the playback of the stream at regular intervals. While this is fine when the video is played on the device's screen and over AirPlay while the app is in the foreground, it isn't possible to do with the app in the background.
The solution I've gone with instead is to disable the idle timer during all types of playback and to re-enable afterwards using:
[UIApplication sharedApplication].idleTimerDisabled = YES;
and
[UIApplication sharedApplication].idleTimerDisabled = NO;
While this isn't a solution to the original question, it's a workaround for avoiding the issue in the first place.
I need to display more than one movieplayer in a view.
I know I can only play one video.
My problem is that only one of the two MPMovieplayer, I have added to the view, shows me the control buttons.
What can I do to solve my problem?
I use this code to add a movieplayer:
MPMoviePlayerController * moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerPlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerDidEnterFullscreen:)
name:MPMoviePlayerDidEnterFullscreenNotification
object:moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerDidExitFullscreen:)
name:MPMoviePlayerDidExitFullscreenNotification
object:moviePlayer];
moviePlayer.view.frame = rect;
[movie setContentURL:contentURL];
[movie prepareToPlay];
[self addSubview:moviePlayer.view];
I think its not possible. Please see the answer for this question
Playing Multiple Videos on iPAD
You will have to use AVPlayer for multiple video viewing, see this
Here is another tutorial for AVPlayer
You can also check this from apple developer portal, link
This question also says something about adding controls to AVPlayer
BR, Hari
Hi this is not possible to play more than 1 video in ios because only one thread at a time .
I face same issue in my iPad application but I've found an alternate solution.
I want to play more video in 1 view controller , but these videos are 4 to 5 sec's only.
I make number of continuous image frames of that video's and make .gif files and show this in a UIWebView. it works fine.
I want to play two video in iPhone simultaneously.
There are two way to play video in iphone, One is use AVQueuePlayer. but in this controller I don't get how get the video playing is completed and how to restart video again.
Another way is MPMoviePlayerController . but in this controller I don't get how to seek video at particular time and also it is not able to play two video simultaneously as the AVQueuePlayer is able to play.
as a solution i am using AVQueuePlayer to play video and but can any one help me to restart video and get method to detect end point of the video. or know any other api to so this
Thanks in advance.
I have found the solution to play two video . You can use AVQueuePlayer to play video. Using this controller you can play two video at the same time .
I wonder if this is even possible. Video playback on the iPhone is ensured thanks to a hardware video decoder. And I really think the hardware decoder can only handle one video stream at a time.
Ecco is correct. You're limited to one video at a time due to hardware restrictions.
However, if you're after 7KV7's suggestion of one video ending and triggering the playback of another, you can make use of the MPMoviePlayerPlaybackDidFinishNotification notification in the following way:
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(firstMoviePlayerDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}
- (void)moviePlayerDidFinish:(NSNotification *)notification {
if (firstMovie) {
[moviePlayerController setContentURL:nextMovieURL];
[moviePlayerController play];
} else {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
Also, note that you can find the current playback point in a MPMoviePlayerController instance by examining the currentPlaybackTime property.
I am new to xcode, interface builder, and the iphone simulator. I am trying to play a movie/video in xcode on the click of a button (which is very straightforward). I am using xcode 3.2.4 and iphone simulator 4.1.
When I launch the iPhone simulator and click the button to launch the video, the audio plays, but the video is hidden. It's as if the video is behind the tab bar (this is part of a tab bar application). I am not sure how to make the video play in front.
Here's the code:
-(IBAction)launchVideo2:(id)sender{
NSString *movieFile;
MPMoviePlayerController *moviePlayer;
movieFile = [[NSBundle mainBundle]
pathForResource:#"IGDIs_Video_Picture_Naming_iPhone" ofType:#"mp4"];
moviePlayer = [[MPMoviePlayerController alloc]
initWithContentURL: [NSURL fileURLWithPath: movieFile]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playMediaFinished:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
[moviePlayer play];
}
-(void)playMediaFinished:(NSNotification*)theNotification
{
MPMoviePlayerController *moviePlayer=[theNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:moviePlayer];
[moviePlayer release];
}
Any suggestions would be great!
should be using the MPMoviePlayerViewcontroller
see apple documentation
http://developer.apple.com/library/ios/#documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/MPMoviePlayerController/MPMoviePlayerController.html
It doesn't look like you have added the movie view to your main view. You'll need to add something like:
...
[[moviePlayer view] setFrame:[self view] bounds]];
[[self view] addSubview:[moviePlayer view]];
[moviePlayer play];
}
before playing it. I'm assuming that the a launchVideo2 method is in a UIViewController that owns the main view. You might have to change [self view] to suit your code to correspond to the view where you want the movie to play.
In my experience, video won't display in the sim. However, audio will. (Which is an improvement, since previously neither would play.)
Try running the app on the device. If the video doesn't display there, post here and we'll work through the issue.
You have a probably unrelated memory issue there:
In your first method, you don't release the player, which is a local variable.
In your second method, you release the player, that you don't own.
Proper memory management (ie best practice), you would do this with an ivar.