I want to play an animation(Gif) or a movie instead of Default.png. Is that possible? I tried what is described in this blog :http://www.cuppadev.co.uk/iphone/playing-animated-gifs-on-the-iphone/ but I don't know how to play a Gif animation instead of Default.png
If you're asking about a sanctioned App Store app, then no, you can't use anything but a static Default.png.
If you're writing an app for jailbroken phone, this may be possible (but I don't know).
The Following code should come in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
NSBundle *bundle = [NSBundle mainBundle];
if(bundle != nil)
{
NSString *videoPath = [bundle pathForResource:#"trail_video" ofType:#"mp4"];
if (moviePath)
{
videoURL = [NSURL fileURLWithPath:moviePath];
}
}
theMovie = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
theMovie.moviePlayer.controlStyle = MPMovieControlStyleNone;
theMovie.moviePlayer.scalingMode = MPMovieScalingModeFill;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie.moviePlayer];
[theMovie.moviePlayer setFullscreen:YES animated:NO];
[theMovie.moviePlayer prepareToPlay];
[theMovie.moviePlayer play];
window.rootViewController = theMovie;
[self.window.rootViewController.view bringSubviewToFront:mMoviePlayer.moviePlayer.view];
In the moviePlayerDidFinish method load the screen which you desire to load.
Unfortunately, it's impossible to do it on the latest iPhone OS. A trick using symbolic link is currently blocked by OS.
Related
I'm doing this test app where I want to receive notification when the iPod changes the now playing item (song), the test is working nice while app is in foreground but as soon as the app goes to the background it stop getting notifications which is OK, when I tap on the app again (comes to foreground) I get all notifications according to all the times the now playing changed while the app was in background but everytime I'm getting the same song information, so how can I get the correct song information for each notification?
This is the test I did, in the AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
MPMusicPlayerController *player = [MPMusicPlayerController iPodMusicPlayer];
[notificationCenter addObserver:self
selector:#selector(nowPlayingItemChanged:)
name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object:player];
[player beginGeneratingPlaybackNotifications];
return YES;
}
-(void) nowPlayingItemChanged:(NSNotification *)notification {
MPMusicPlayerController *player = (MPMusicPlayerController *)notification.object;
MPMediaItem *song = [player nowPlayingItem];
if (song) {
NSString *title = [song valueForProperty:MPMediaItemPropertyTitle];
NSString *album = [song valueForProperty:MPMediaItemPropertyAlbumTitle];
NSString *artist = [song valueForProperty:MPMediaItemPropertyArtist];
NSString *playCount = [song valueForProperty:MPMediaItemPropertyPlayCount];
NSLog(#"title: %#", title);
NSLog(#"album: %#", album);
NSLog(#"artist: %#", artist);
NSLog(#"playCount: %#", playCount);
}
}
See this post your options in the background are pretty restricted:
StackOverFlow Post
And the Apple Docs regarding that state it is not really possible:
Apple Documentation on Background states
Be sure to remove the observer when going into the background:
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification object:musicPlayer];[player endGeneratingPlaybackNotifications];
Add it again when entering the foreground.
I'm trying to load a 25-second mp4 movie from my resource file, but when I play it, my MPMoviePlayerPlaybackDidFinishNotification selector is called immediately with MPMovieFinishReasonPlaybackEnded. When I log my playback state it shows this:
MPMoviePlaybackStatePlaying
MPMoviePlaybackStatePaused
MPMoviePlaybackStateStopped
MovieFinishReasonPlaybackEnded
MPMoviePlaybackStatePlaying
MPMoviePlaybackStatePaused
even though I only call the play method once. I hope someone can help me.
-- Edited to show my code:
MPMoviePlayerController* player = [[[MPMoviePlayerController alloc] initWithContentURL:movieURL] autorelease];
if (player)
{
self.moviePlayerController = player;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackStateDidChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:player];
player.contentURL = movieURL;
player.movieSourceType = MPMovieSourceTypeFile;
player.controlStyle = MPMovieControlStyleNone;
player.fullscreen = YES;
switch (orientation) {
case UIInterfaceOrientationLandscapeLeft:
player.view.transform = CGAffineTransformMakeRotation(90.0f * (M_PI / 180.0f));
break;
case UIInterfaceOrientationLandscapeRight:
player.view.transform = CGAffineTransformMakeRotation(-90.0f * (M_PI / 180.0f));
break;
default:
break;
}
player.view.frame = self.view.bounds;
[self.view addSubview:player.view];
}
[self.moviePlayerController play]
Is self.moviePlayerController a retained property? If not, the MPMoviePlayerController instance will be released very quickly (by the autorelease), and you might get similar behaviour.
Without having any more of your code to look at, I would suggest trying to play another file that you know can play. For example, grab the movie from this sample project: http://developer.apple.com/library/ios/#samplecode/MoviePlayer_iPhone/Introduction/Intro.html and see if it plays.
I had something similar happen to me when I was trying to play a file that wasn't properly formatted.
Hmm... I don't see what's wrong. Are you sure that movieURL is correct? How do you get it?
For the record, here is how I present movies, although it wouldn't have quite the same effect as what you're doing.
NSString *path = [[NSBundle mainBundle] pathForResource:movieFileName ofType:#"m4v"];
// If path is NULL (the resource does not exist) return to avoid crash
if (path == NULL)
return;
NSURL *url = [NSURL fileURLWithPath:path];
MPMoviePlayerViewController *mpViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
mpViewController.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
mpViewController.moviePlayer.shouldAutoplay = YES;
// NOTE: This can sometimes crash the app in the Simulator. This is a known bug
// in xcode: http://stackoverflow.com/a/8317546/472344
[self presentMoviePlayerViewControllerAnimated:mpViewController];
[mpViewController release];
I have subfolder called "Video" in Documents folder. And there is somevideo.mp4 file. I have full path to this file but MPMoviePlayerViewController doesn't want to play video from local. Here is code:
NSString *path = [[self getVideoFolderPath] stringByAppendingPathComponent:#"somevideo.mp4"];
NSURL *fURL = [NSURL fileURLWithPath:path];
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:fURL];
[self presentMoviePlayerViewControllerAnimated:videoPlayerView];
[videoPlayerView.moviePlayer play];
It doesn't play. Appears white screen and nothing else. This code works with remote video, when i put URL to website with video file, but local doesn't play. How to get correct file path to video file?
Are you using iOS prior to 4.3? If so, you need to do this
[videoPlayerView setContentURL: fURL];
Here is a snippet of code from where I play video from the documents folder. One of the things I would recommend is to avoid some of the autorelease objects. Especially on NSURL when you have viewcontrollers. I know it should be safe but I've never found it to be 100%
if ( [[NSFileManager defaultManager] fileExistsAtPath:fullpathVideoFile] == NO )
{
NSLog(#"No video file found");
return self;
}
playbackURL = [[NSURL alloc] initFileURLWithPath:fullpathVideoFile isDirectory:NO];
if ( playbackURL == nil )
{
NSLog(#"playbackURL == nil");
return self;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerLoadedMovie:) name:#"MPMoviePlayerLoadStateDidChangeNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerStartedMovie:) name:#"MPMoviePlayerNowPlayingMovieDidChangeNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerFinishedMovie:) name:#"MPMoviePlayerPlaybackDidFinishNotification" object:nil];
[self setContentURL:playbackURL];
In my case, I created a subclass of MPMoviePlayerController (as I generally do with all view controllers) so the references to 'self' would be to the MPMoviePlayerController object instance
Strange. The code you put seems to be correct. Make sure the path to the audio you are trying to retrieve isn't broken.
I need to have the possibility to play more than one video in an app.
Unfortunately, the second time I press play, video appears blinking.
I use only this code for playing vide
NSURL *url = [[[NSURL alloc]initFileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Movie" ofType:#"m4v"]] autorelease];
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc]initWithContentURL:url];
mp.movieControlMode = MPMovieControlModeDefault;
[mp play];
moviePlayer = mp;
[mp release];
Can anyone tell me where can be the problem?
Thanks in advance!
UPDATE 1: It seems that the Apple MoviePlayer example has the same problem.
you can also do it by setting the initial playback time to -1.0 before calling the play function
mp.initialPlaybackTime = -1.0;
Put this code before ur play method is called.
I had this problem and solved it by using the notification system to execute a callback after the MPMoviePlayerController finishes playing, and releasing the player object there.
Add a notification before you play the movie:
NSURL *url = [[[NSURL alloc]initFileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Movie" ofType:#"m4v"]] autorelease];
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc]initWithContentURL:url];
mp.movieControlMode = MPMovieControlModeDefault;
//***Add this line***
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMovieFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:mp];
[mp play];
Then add the callback method,
-(void)myMovieFinished:(NSNotification*)aNotification
{
MPMoviePlayerController *moviePlayer = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerDidFinishNotification object:moviePlayer];
[moviePlayer release];
}
It seams that the only solution is... to make the app for 3.1
I also find run on the OS 3.1 or later version of simulator can be played well.It won't appears blinking.But when I add
initialPlaybackTime = -1.0
it will also play well on OS 3.0.
How can I play a background audio while my application is running?
Thanks.
Okay. This is a solution for background sound on iOS4 & iOS5 (definitely works up to iOS 5.0.1), and I have tested it only with AVPlayer. It should probably work for MPMusicPlayerController too.
Required frameworks:
AVFoundation.framework
AudioToolbox.framework
In your Info.plist, for the key UIBackgroundModes, add audio.
In MyAppDelegate.h:
reference <AVFoundation/AVFoundation.h> & <AudioToolbox/AudioToolbox.h>
implement the protocol AVAudioSessionDelegate:
#interface MyAppDelegate : NSObject <UIApplicationDelegate, AVAudioSessionDelegate>
define a method ensureAudio:
// Ensures the audio routes are setup correctly
- (BOOL) ensureAudio;
In MyAppDelegate.m:
implement the ensureAudio method:
- (BOOL) ensureAudio
{
// Registers this class as the delegate of the audio session (to get background sound)
[[AVAudioSession sharedInstance] setDelegate: self];
// Set category
NSError *categoryError = nil;
if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&categoryError]) {
NSLog(#"Audio session category could not be set");
return NO;
}
// Activate session
NSError *activationError = nil;
if (![[AVAudioSession sharedInstance] setActive: YES error: &activationError]) {
NSLog(#"Audio session could not be activated");
return NO;
}
// Allow the audio to mix with other apps (necessary for background sound)
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);
return YES;
}
in the application:didFinishLaunchingWithOptions: method, before you assign the root view controller, run [self ensureAudio]:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Configure audio session
[self ensureAudio];
// Add the navigation controller's view to the window and display.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
implement the AVAudioSessionDelegate methods like this:
#pragma mark - AVAudioSessionDelegate
- (void) beginInterruption
{
}
- (void) endInterruption
{
// Sometimes the audio session will be reset/stopped by an interruption
[self ensureAudio];
}
- (void) inputIsAvailableChanged:(BOOL)isInputAvailable
{
}
ensure that your app continues to run in the background. You can use the ol' [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler] if you want, but I think there are better ways.
play the actual audio (note I'm using ARC, that's why there are no release calls):
NSURL * file = [[NSBundle mainBundle] URLForResource:#"beep" withExtension:#"aif"];
AVURLAsset * asset = [[AVURLAsset alloc] initWithURL:file options:nil];
AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:asset];
__block AVPlayer * player = [[AVPlayer alloc]initWithPlayerItem:item];
__block id finishObserver = [[NSNotificationCenter defaultCenter] addObserverForName:AVPlayerItemDidPlayToEndTimeNotification
object:player.currentItem
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[[NSNotificationCenter defaultCenter] removeObserver:finishObserver];
// Reference the 'player' variable so ARC doesn't release it until it's
// finished playing.
player = nil;
}];
// Trigger asynchronous load
[asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:#"tracks"] completionHandler:^{
// Start playing the beep (watch out - we're not on the main thread here)!
[player play];
}];
And it shooooooooooooould work!
If you are using your app also for recording - then don't forget to change setCategory to AVAudioSessionCategoryPlayAndRecord. In other case you won't be able to record
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord error:&setCategoryErr];