AVAudioPlayer is playing again without being called play. - iphone

I have 2 views and video player and an audio player. when button on the first view is pressed. then audio and a video player start playing. And after the movie has stopped playing. next view is appear. when i press back button on the second view same audio is playing. Dont know where to start
- (id) init {
if (self = [super init]) {
movieName = #"03";
self.view = [[[OtsugeView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
}
return self;
}
- (void) toNext {
NSLog(#"OtsugeViewController:toNext");
[self.navigationController popViewControllerAnimated:NO];
}
- (void) toToppage
{
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:NO];
[self.navigationController popToRootViewControllerAnimated:NO];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"Screen touch Otsuge View");
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Retry", #"Main Menu", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
actionSheet.cancelButtonIndex = 0;
[actionSheet showInView:self.view]; // show from our table view (pops up in the middle of the table)
[actionSheet release];
}
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex: (NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0: // Retry
[self presentModalViewController:mMoviePlayer animated:YES];
[self play];
break;
case 1: // Main Menu
[self toToppage];
break;
case 2: // Cancel
break;
default:
break;
}
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
mMoviePlayer.moviePlayer.backgroundView.backgroundColor = [UIColor blackColor];
[self playSound:#"taiko_1"];
[(OtsugeView *)self.view renewImageView];
}
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
- (void) dealloc {
[super dealloc];
}
#end
and the movieplayerclass is
- (NSURL *)createURL
{
NSURL *mvURL;
NSBundle *bundle = [NSBundle mainBundle];
if (movieName != nil) {
if (bundle) {
NSString *mvPath = [bundle pathForResource:movieName ofType:#"m4v"];
if (mvPath) {
mvURL = [NSURL fileURLWithPath:mvPath];
}
}
}
return mvURL;
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[aAudioPlayer setDelegate:nil];
[aAudioPlayer release];
NSLog(#"MovieViewController:audioHasFinished");
NSLog(#"%#", aAudioPlayer.url);
}
- (void)playSound:(NSString *)file {
NSURL *avURL;
NSString *avPath = [[NSBundle mainBundle] pathForResource:file ofType:#"m4a"];
if (avPath) {
avURL = [NSURL fileURLWithPath:avPath];
aAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:avURL error:nil];
[aAudioPlayer setDelegate:self];
[aAudioPlayer play];
NSLog(#"MovieViewController:playSound");
}
}
- (void)toNext {
// implementation sub classes
NSLog(#"MovieViewController:toNext");
}
- (void) clearVideo{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:mMoviePlayer.moviePlayer];
[mMoviePlayer release];
mMoviePlayer = nil;
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
NSLog(#"MovieViewController:moviePlaybackDidFinish");
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:NO];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:mMoviePlayer.moviePlayer];
[self dismissModalViewControllerAnimated:YES];
[mMoviePlayer release];
mMoviePlayer = nil;
mPlayerPushed = NO;
[self toNext];
}
- (void) moviePreloadDidFinish : (NSNotification *)notification{
[self prepareFinished];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:mMoviePlayer.moviePlayer];
}
- (void) prepareFinished{
}
- (void) initPlayer{
if (mMoviePlayer != nil) {
[mMoviePlayer release];
}
mMoviePlayer = [[MoviePlayerViewController alloc] initWithContentURL:[self createURL]];
// Added 3.2 versions
[[NSNotificationCenter defaultCenter] removeObserver:mMoviePlayer
name:MPMoviePlayerPlaybackDidFinishNotification object:mMoviePlayer.moviePlayer];
[mMoviePlayer.moviePlayer setShouldAutoplay:NO];
mMoviePlayer.moviePlayer.backgroundView.backgroundColor = [UIColor blackColor];
mMoviePlayer.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
mMoviePlayer.moviePlayer.controlStyle = MPMovieControlStyleNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mMoviePlayer.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePreloadDidFinish:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:mMoviePlayer.moviePlayer];
mPlayerPushed = YES;
}
- (void) play {
NSLog(#"MovieViewController:play");
[mMoviePlayer.moviePlayer prepareToPlay];
[mMoviePlayer.moviePlayer play];
}
- (void)viewWillAppear:(BOOL) animated {
if (!mMoviePlayer) {
[self initPlayer];
}
[super viewWillAppear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
NSLog(#"memory error!");
// Releases the view if it doesn't have a superview.
//[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
}
- (void)dealloc {
[nextController release];
[movieName release];
[super dealloc];
}
#end

The problem is in your second block of code:
The - (void) viewWillAppear:(BOOL)animated method has the following line in it:
[self playSound:#"taiko_1"];
This makes it play the sound, every time that the view is shown, including being shown a second time after dismissing a different view controller.
If you only want it to play once, then you need to move it somewhere else like viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
[self playSound:#"taiko_1"];
}

Related

Can not dismiss Modal View Controller with ios5

I present one controller to play video:
[self presentModalViewController:movieController animated:YES];
and add an observer when finish palying:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(movieFinishedPlayback:)
name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}
-(void) movieFinishedPlayback:(NSNotification*)notification{
NSLog(#"........movieFinishedPlayback....... \n ");
[self dismissModalViewControllerAnimated:YES];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}
This my VideoDetailViewController:
#import "VideoDetailViewController.h"
#import "PSStackedView.h"
#import "YunMaoIpadAppDelegate.h"
#define IpadAppDelegate ((YunMaoIpadAppDelegate *)[[UIApplication sharedApplication] delegate])
#define IphoneAppDelegate ((YunMaoIosAppDelegate *)[[UIApplication sharedApplication] delegate])
#interface VideoDetailViewController ()
#end
#implementation VideoDetailViewController
#synthesize video, moviePlayer, collectionsArray;
-(id)initWithVideo:(Video *)theVideo
{
self = [super initWithNibName:#"VideoDetailViewController" bundle:nil];
if (self) {
self.video = theVideo;
}
return self;
}
- (void)viewWillDisappear:(BOOL)animated
{
[moviePlayer pause];
//[self.navigationController setNavigationBarHidden:false animated:animated];
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated;
{
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
[super viewDidDisappear:animated];
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.view.backgroundColor = [UIColor blackColor];
}
- (void) viewDidAppear:(BOOL)animated
{
//[moviePlayer play];
//[DejalBezelActivityView removeViewAnimated:YES];
[super viewDidAppear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(displayActivityView) withObject:self.moviePlayer.view afterDelay:0.1];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:video.link]];
[moviePlayer prepareToPlay];
//[moviePlayer setShouldAutoplay:NO];
moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
if([moviePlayer respondsToSelector:#selector(useApplicationAudioSession)])
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
NSLog(#"iPhone ios5.x");
[moviePlayer.view setFrame: CGRectMake(0.0f, 0.0f, 480.0f, 320.0f)];
//moviePlayer.view.transform = CGAffineTransformConcat(moviePlayer.view.transform, CGAffineTransformMakeRotation(M_PI_2));
}
else{
NSLog(#"iPad ios5.x");
[moviePlayer.view setFrame: CGRectMake(0.0f, 0.0f, 1024.0f, 768.0f)];
moviePlayer.view.transform = CGAffineTransformConcat(moviePlayer.view.transform, CGAffineTransformMakeRotation(M_PI_2));
[moviePlayer.view setFrame:[IpadAppDelegate window].bounds];
}
}
else
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
moviePlayer.view.transform = CGAffineTransformConcat(moviePlayer.view.transform, CGAffineTransformMakeRotation(M_PI_2));
NSLog(#"iPhone ios6.x");
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
[moviePlayer.view setFrame: CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
}
if(result.height == 568)
{
//moviePlayer.controlStyle = MPMovieControlStyleDefault;
[moviePlayer.view setFrame:self.view.bounds];
}
}
else{
NSLog(#"ipad ios 6.x");
[moviePlayer.view setFrame: CGRectMake(0.0f, 0.0f, 1024.0f, 768.0f)];
//[moviePlayer.view setFrame:[IpadAppDelegate window].bounds];
}
}
[self.view addSubview:moviePlayer.view];
[moviePlayer play];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation==UIInterfaceOrientationLandscapeLeft || interfaceOrientation==UIInterfaceOrientationLandscapeRight)
return YES;
return NO;
}
- (BOOL)shouldAutorotate{
return NO;
}
/*
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationLandscapeRight;
}
*/
- (IBAction)displayActivityView
{
[DejalBezelActivityView activityViewForView:self.moviePlayer.view withLabel:#"节目正在下载中,请稍后..."].showNetworkActivityIndicator = NO;
}
- (void)removeActivityView;
{
[DejalBezelActivityView removeViewAnimated:YES];
[[self class] cancelPreviousPerformRequestsWithTarget:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
This worked for me.
[self dismissViewControllerAnimated:NO completion:^{
[self.view removeFromSuperview];
}];
Hope it helps!
Before dismissing movieplayer do [moviePlayer stop]; and remove movieplayer.view from superview. Try dismissing after that. That might fix the issue.

shake action catched in other views?

I have a simple app which consists of 2 views. Top view has a accelerometer delegates. when user shakes while top view is on the screen. then pushviewcontroller is called and subview will appear. the problem is when subview is appeard, i shake it, it still catches the shake action and results me an error. So help me. thanks in advance.
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
const float violence = 1.2;
static BOOL beenhere;
BOOL shake = FALSE;
if (beenhere) return;
beenhere = TRUE;
if (acceleration.x > violence || acceleration.x < (-1* violence))
shake = TRUE;
if (acceleration.y > violence || acceleration.y < (-1* violence))
shake = TRUE;
if (acceleration.z > violence || acceleration.z < (-1* violence))
shake = TRUE;
if (shake) {
[self playSound:#"suzu"];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"noVib"] == NO) {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
[[UIAccelerometer sharedAccelerometer] setDelegate:nil];
[self presentModalViewController:mMoviePlayer animated:YES];
[self play];
}
when play method called and video has finished, pushviewcontroller will be called and the sub view will appear
below is a class that handles all the movieplayer stuff.
- (void) initPlayer{
if (mMoviePlayer != nil){
[mMoviePlayer release];
}
mMoviePlayer = [[MoviePlayerViewController alloc] initWithContentURL:[self createURL]];
[[NSNotificationCenter defaultCenter] removeObserver:mMoviePlayer
name:MPMoviePlayerPlaybackDidFinishNotification object:mMoviePlayer.moviePlayer];
[mMoviePlayer.moviePlayer setShouldAutoplay:NO];
mMoviePlayer.moviePlayer.backgroundView.backgroundColor = [UIColor blackColor];
mMoviePlayer.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
mMoviePlayer.moviePlayer.controlStyle = MPMovieControlStyleNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mMoviePlayer.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePreloadDidFinish:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:mMoviePlayer.moviePlayer];
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:NO];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:mMoviePlayer.moviePlayer];
[self dismissModalViewControllerAnimated:YES];
[mMoviePlayer release];
mMoviePlayer = nil;
[self toNext];
}
The first thing that comes into my mind is to keep track if the mMoviePlayer is pushed or not.
if (shake && mPlayerPushed) {
[self playSound:#"suzu"];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"noVib"] == NO) {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
[[UIAccelerometer sharedAccelerometer] setDelegate:nil];
[self presentModalViewController:mMoviePlayer animated:YES];
[self play];
mPlayerPushed = YES;
}
in the moviePlayBackDidFinish method after you call dismissModalViewControllerAnimated:YES you should set the mPlayerPushed to NO.
or you could use the property modal view controller to see if a modal view is displayed. This i haven't tested yet but it should work.
modalViewController: The controller for the active modal view—that is,
the view that is temporarily displayed on top of the view managed by
the receiver. (read-only)
#property(nonatomic, readonly) UIViewController *modalViewController
so instead of the bool mPlayerPushed you will have:
if(shake && something.modalviewController == nil){ present mMoviePlayer }

Can avplayer play music from mpmusicplayercontroller

is this possible AVPlayer fetch music from ipodlibrary from MPMusicPlayerController and play ,since avplayer cannot access iPodMusicPlayer from MPMusicPlayerController , since AVPlayer support background playing and access to remoteEvents.
The code shown below is from addMusic project. so any help would be appreciated .Thank you
void audioRouteChangeListenerCallback (
void *inUserData,
AudioSessionPropertyID inPropertyID,
UInt32 inPropertyValueSize,
const void *inPropertyValue
) {
// ensure that this callback was invoked for a route change
if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return;
// This callback, being outside the implementation block, needs a reference to the
// MainViewController object, which it receives in the inUserData parameter.
// You provide this reference when registering this callback (see the call to
// AudioSessionAddPropertyListener).
MainViewController *controller = (MainViewController *) inUserData;
// if application sound is not playing, there's nothing to do, so return.
if (controller.appSoundPlayer.playing == 0 ) {
NSLog (#"Audio route change while application audio is stopped.");
return;
} else {
// Determines the reason for the route change, to ensure that it is not
// because of a category change.
CFDictionaryRef routeChangeDictionary = inPropertyValue;
CFNumberRef routeChangeReasonRef =
CFDictionaryGetValue (
routeChangeDictionary,
CFSTR (kAudioSession_AudioRouteChangeKey_Reason)
);
SInt32 routeChangeReason;
CFNumberGetValue (
routeChangeReasonRef,
kCFNumberSInt32Type,
&routeChangeReason
);
// "Old device unavailable" indicates that a headset was unplugged, or that the
// device was removed from a dock connector that supports audio output. This is
// the recommended test for when to pause audio.
if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {
[controller.appSoundPlayer pause];
NSLog (#"Output device removed, so application audio was paused.");
UIAlertView *routeChangeAlertView =
[[UIAlertView alloc] initWithTitle: NSLocalizedString (#"Playback Paused", #"Title for audio hardware route-changed alert view")
message: NSLocalizedString (#"Audio output was changed", #"Explanation for route-changed alert view")
delegate: controller
cancelButtonTitle: NSLocalizedString (#"StopPlaybackAfterRouteChange", #"Stop button title")
otherButtonTitles: NSLocalizedString (#"ResumePlaybackAfterRouteChange", #"Play button title"), nil];
[routeChangeAlertView show];
// release takes place in alertView:clickedButtonAtIndex: method
} else {
NSLog (#"A route change occurred that does not require pausing of application audio.");
}
}
}
#implementation MainViewController
#synthesize artworkItem;
#synthesize userMediaItemCollection;
#synthesize playBarButton;
#synthesize pauseBarButton;
#synthesize musicPlayer;
#synthesize navigationBar;
#synthesize noArtworkImage; item has no associated artwork
#synthesize backgroundColorTimer;
#synthesize nowPlayingLabel;
#synthesize appSoundButton;
#synthesize addOrShowMusicButton;
#synthesize appSoundPlayer;
#synthesize soundFileURL;
#synthesize interruptedOnPlayback;
#synthesize playedMusicOnce;
#synthesize playing;
#implementation MainViewController
#synthesize artworkItem; // the now-playing media item's artwork image, displayed in the Navigation bar
#synthesize userMediaItemCollection; // the media item collection created by the user, using the media item picker
#synthesize playBarButton; // the button for invoking Play on the music player
#synthesize pauseBarButton; // the button for invoking Pause on the music player
#synthesize musicPlayer; // the music player, which plays media items from the iPod library
#synthesize navigationBar; // the application's Navigation bar
#synthesize noArtworkImage; // an image to display when a media item has no associated artwork
#synthesize backgroundColorTimer; // a timer for changing the background color -- represents an application that is
// doing something else while iPod music is playing
#synthesize nowPlayingLabel; // descriptive text shown on the main screen about the now-playing media item
#synthesize appSoundButton; // the button to invoke playback for the application sound
#synthesize addOrShowMusicButton; // the button for invoking the media item picker. if the user has already
// specified a media item collection, the title changes to "Show Music" and
// the button invokes a table view that shows the specified collection
#synthesize appSoundPlayer; // An AVAudioPlayer object for playing application sound
#synthesize soundFileURL; // The path to the application sound
#synthesize interruptedOnPlayback; // A flag indicating whether or not the application was interrupted during
// application audio playback
#synthesize playedMusicOnce; // A flag indicating if the user has played iPod library music at least one time
// since application launch.
#synthesize playing; // An application that responds to interruptions must keep track of its playing/
// not-playing state.
#pragma mark Music control
- (IBAction) AddMusicOrShowMusic: (id) sender {
// if the user has already chosen some music, display that list
if (userMediaItemCollection) {
MusicTableViewController *controller = [[MusicTableViewController alloc] initWithNibName: #"MusicTableView" bundle: nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController: controller animated: YES];
[controller release];
} else {
MPMediaPickerController *picker =
[[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];
picker.delegate = self;
picker.allowsPickingMultipleItems = YES;
picker.prompt = NSLocalizedString (#"Add songs to play", "Prompt in media item picker");
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleDefault animated: YES];
[self presentModalViewController: picker animated: YES];
[picker release];
}
}
- (void) updatePlayerQueueWithMediaCollection: (MPMediaItemCollection *) mediaItemCollection {
// Configure the music player, but only if the user chose at least one song to play
if (mediaItemCollection) {
if (userMediaItemCollection == nil) {
[self setUserMediaItemCollection: mediaItemCollection];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
[self setPlayedMusicOnce: YES];
[musicPlayer play];
} else {
BOOL wasPlaying = NO;
if (musicPlayer.playbackState == MPMusicPlaybackStatePlaying) {
wasPlaying = YES;
}
MPMediaItem *nowPlayingItem = musicPlayer.nowPlayingItem;
NSTimeInterval currentPlaybackTime = musicPlayer.currentPlaybackTime;
NSMutableArray *combinedMediaItems = [[userMediaItemCollection items] mutableCopy];
NSArray *newMediaItems = [mediaItemCollection items];
[combinedMediaItems addObjectsFromArray: newMediaItems];
[self setUserMediaItemCollection: [MPMediaItemCollection collectionWithItems: (NSArray *) combinedMediaItems]];
[combinedMediaItems release];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
musicPlayer.nowPlayingItem = nowPlayingItem;
musicPlayer.currentPlaybackTime = currentPlaybackTime;
if (wasPlaying) {
[musicPlayer play];
}
}
navigationBar.topItem.leftBarButtonItem.enabled = YES;
[addOrShowMusicButton setTitle: NSLocalizedString (#"Show Music", #"Alternate title for 'Add Music' button, after user has chosen some music")
forState: UIControlStateNormal];
}
}
- (void) restorePlaybackState {
if (musicPlayer.playbackState == MPMusicPlaybackStateStopped && userMediaItemCollection) {
[addOrShowMusicButton setTitle: NSLocalizedString (#"Show Music", #"Alternate title for 'Add Music' button, after user has chosen some music")
forState: UIControlStateNormal];
if (playedMusicOnce == NO) {
[self setPlayedMusicOnce: YES];
[musicPlayer play];
}
}
}
#pragma mark Media item picker delegate methods________
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection {
[self dismissModalViewControllerAnimated: YES];
[self updatePlayerQueueWithMediaCollection: mediaItemCollection];
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque animated: YES];
}
- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker {
[self dismissModalViewControllerAnimated: YES];
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque animated: YES];
}
#pragma mark Music notification handlers__________________
- (void) handle_NowPlayingItemChanged: (id) notification {
MPMediaItem *currentItem = [musicPlayer nowPlayingItem];
UIImage *artworkImage = noArtworkImage;
MPMediaItemArtwork *artwork = [currentItem valueForProperty: MPMediaItemPropertyArtwork];
// Obtain a UIImage object from the MPMediaItemArtwork object
if (artwork) {
artworkImage = [artwork imageWithSize: CGSizeMake (30, 30)];
}
// Obtain a UIButton object and set its background to the UIImage object
UIButton *artworkView = [[UIButton alloc] initWithFrame: CGRectMake (0, 0, 30, 30)];
[artworkView setBackgroundImage: artworkImage forState: UIControlStateNormal];
// Obtain a UIBarButtonItem object and initialize it with the UIButton object
UIBarButtonItem *newArtworkItem = [[UIBarButtonItem alloc] initWithCustomView: artworkView];
[self setArtworkItem: newArtworkItem];
[newArtworkItem release];
[artworkItem setEnabled: NO];
[navigationBar.topItem setRightBarButtonItem: artworkItem animated: YES];
[nowPlayingLabel setText: [
NSString stringWithFormat: #"%# %# %# %#",
NSLocalizedString (#"Now Playing:", #"Label for introducing the now-playing song title and artist"),
[currentItem valueForProperty: MPMediaItemPropertyTitle],
NSLocalizedString (#"by", #"Article between song name and artist name"),
[currentItem valueForProperty: MPMediaItemPropertyArtist]]];
if (musicPlayer.playbackState == MPMusicPlaybackStateStopped) {
[nowPlayingLabel setText: [
NSString stringWithFormat: #"%#",
NSLocalizedString (#"Music-ended Instructions", #"Label for prompting user to play music again after it has stopped")]];
}
}
- (void) handle_PlaybackStateChanged: (id) notification {
MPMusicPlaybackState playbackState = [musicPlayer playbackState];
if (playbackState == MPMusicPlaybackStatePaused) {
navigationBar.topItem.leftBarButtonItem = playBarButton;
} else if (playbackState == MPMusicPlaybackStatePlaying) {
navigationBar.topItem.leftBarButtonItem = pauseBarButton;
} else if (playbackState == MPMusicPlaybackStateStopped) {
navigationBar.topItem.leftBarButtonItem = playBarButton;
// Even though stopped, invoking 'stop' ensures that the music player will play
// its queue from the start.
[musicPlayer stop];
}
}
- (void) handle_iPodLibraryChanged: (id) notification {
]
}
#pragma mark Application playback control_________________
- (IBAction) playAppSound: (id) sender {
[appSoundPlayer play];
playing = YES;
[appSoundButton setEnabled: NO];
}
- (void) alertView: routeChangeAlertView clickedButtonAtIndex: buttonIndex {
if ((NSInteger) buttonIndex == 1) {
[appSoundPlayer play];
} else {
[appSoundPlayer setCurrentTime: 0];
[appSoundButton setEnabled: YES];
}
[routeChangeAlertView release];
}
#pragma mark AV Foundation delegate methods____________
- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) appSoundPlayer successfully: (BOOL) flag {
playing = NO;
[appSoundButton setEnabled: YES];
}
- (void) audioPlayerBeginInterruption: player {
NSLog (#"Interrupted. The system has paused audio playback.");
if (playing) {
playing = NO;
interruptedOnPlayback = YES;
}
}
- (void) audioPlayerEndInterruption: player {
NSLog (#"Interruption ended. Resuming audio playback.");
[[AVAudioSession sharedInstance] setActive: YES error: nil];
if (interruptedOnPlayback) {
[appSoundPlayer prepareToPlay];
[appSoundPlayer play];
playing = YES;
interruptedOnPlayback = NO;
}
}
#pragma mark Table view delegate methods
- (void) musicTableViewControllerDidFinish: (MusicTableViewController *) controller {
[self dismissModalViewControllerAnimated: YES];
[self restorePlaybackState];
}
#pragma mark Application setup
- (void) setupApplicationAudio {
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: #"sound"
ofType: #"caf"];
NSURL *newURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
self.soundFileURL = newURL;
[newURL release];
[[AVAudioSession sharedInstance] setDelegate: self];
// [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
UInt32 doSetProperty = 0;
AudioSessionSetProperty (
kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof (doSetProperty),
&doSetProperty
);
// Registers the audio route change listener callback function
AudioSessionAddPropertyListener (
kAudioSessionProperty_AudioRouteChange,
audioRouteChangeListenerCallback,
self
);
// Activates the audio session.
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
// Instantiates the AVAudioPlayer object, initializing it with the sound
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: soundFileURL error: nil];
self.appSoundPlayer = newPlayer;
[newPlayer release];
[appSoundPlayer prepareToPlay];
[appSoundPlayer setVolume: 1.0];
[appSoundPlayer setDelegate: self];
}
- (void) registerForMediaPlayerNotifications {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self
selector: #selector (handle_NowPlayingItemChanged:)
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object: musicPlayer];
[notificationCenter addObserver: self
selector: #selector (handle_PlaybackStateChanged:)
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification
object: musicPlayer];
[musicPlayer beginGeneratingPlaybackNotifications];
}
- (BOOL) useiPodPlayer {
if ([[NSUserDefaults standardUserDefaults] boolForKey: PLAYER_TYPE_PREF_KEY]) {
return YES;
} else {
return NO;
}
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent {
if (receivedEvent.type == UIEventTypeRemoteControl) {
switch (receivedEvent.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
[self togglePlayPause];
break;
case UIEventSubtypeRemoteControlPlay:
[self playAudio];
break;
case UIEventSubtypeRemoteControlPause:
[self pauseAudio];
break;
default:
break;
}
}
}
- (IBAction) playOrPauseMusic: (id)sender {
[self togglePlayPause];
}
- (void)playAudio {
[musicPlayer play];
}
- (void)pauseAudio {
[musicPlayer pause];
}
- (void)togglePlayPause {
MPMusicPlaybackState playbackState = [musicPlayer playbackState];
if (playbackState == MPMusicPlaybackStateStopped || playbackState == MPMusicPlaybackStatePaused) {
[musicPlayer play];
} else if (playbackState == MPMusicPlaybackStatePlaying) {
[musicPlayer pause];
}
}
// Configure the application.
- (void) viewDidLoad {
[super viewDidLoad];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self setupApplicationAudio];
[self setPlayedMusicOnce: NO];
[self setNoArtworkImage: [UIImage imageNamed: #"no_artwork.png"]];
[self setPlayBarButton: [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemPlay
target: self
action: #selector (playOrPauseMusic:)]];
[self setPauseBarButton: [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemPause
target: self
action: #selector (playOrPauseMusic:)]];
[addOrShowMusicButton setTitle: NSLocalizedString (#"Add Music", #"Title for 'Add Music' button, before user has chosen some music")
forState: UIControlStateNormal];
[appSoundButton setTitle: NSLocalizedString (#"Play App Sound", #"Title for 'Play App Sound' button")
forState: UIControlStateNormal];
[nowPlayingLabel setText: NSLocalizedString (#"Instructions", #"Brief instructions to user, shown at launch")];
if ([self useiPodPlayer]) {
[self setMusicPlayer: [MPMusicPlayerController iPodMusicPlayer]];
if ([musicPlayer nowPlayingItem]) {
navigationBar.topItem.leftBarButtonItem.enabled = YES;
[self handle_NowPlayingItemChanged: nil];
if ([musicPlayer playbackState] == MPMusicPlaybackStatePaused) {
navigationBar.topItem.leftBarButtonItem = playBarButton;
}
}
} else {
[self setMusicPlayer: [MPMusicPlayerController applicationMusicPlayer]];
[musicPlayer setShuffleMode: MPMusicShuffleModeOff];
[musicPlayer setRepeatMode: MPMusicRepeatModeNone];
}
[self registerForMediaPlayerNotifications];
[self setBackgroundColorTimer: [NSTimer scheduledTimerWithTimeInterval: 3.5
target: self
selector: #selector (updateBackgroundColor)
userInfo: nil
repeats: YES]];
}
// Invoked by the backgroundColorTimer.
- (void) updateBackgroundColor {
[UIView beginAnimations: nil context: nil];
[UIView setAnimationDuration: 3.0];
CGFloat redLevel = rand() / (float) RAND_MAX;
CGFloat greenLevel = rand() / (float) RAND_MAX;
CGFloat blueLevel = rand() / (float) RAND_MAX;
self.view.backgroundColor = [UIColor colorWithRed: redLevel
green: greenLevel
blue: blueLevel
alpha: 1.0];
[UIView commitAnimations];
}
#pragma mark Application state management_____________
- (void) didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void) viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver: self
name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object: musicPlayer];
[[NSNotificationCenter defaultCenter] removeObserver: self
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification
object: musicPlayer];
[musicPlayer endGeneratingPlaybackNotifications];
[musicPlayer release];
[artworkItem release];
[backgroundColorTimer invalidate];
[backgroundColorTimer release];
[navigationBar release];
[noArtworkImage release];
[nowPlayingLabel release];
[pauseBarButton release];
[playBarButton release];
[soundFileURL release];
[userMediaItemCollection release];
[super dealloc];
}
#end
These four lines should get you started :)
MPMediaItem *nowPlayingItem = musicPlayer.nowPlayingItem;
NSURL * mediaURL = [nowPlayingItem valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem * myAVPlayerItem = [AVPlayerItem playerItemWithURL:mediaURL];
AVPlayer * myAvPlayer = [AVPlayer playerWithPlayerItem:myAVPlayerItem];

MPMoviePlayerController with UIPopoverController

I am using the MPMoviePlayerController to play a video on UIPopoverController.
When UIPopoverController dismiss video keeps on playing in background. Is there any way to stop and release MPMoviePlayer.
In my code There is FirstViewController and ViewVideoController which has function:
#implementation FirstViewController
- (void)popOverViewDisplay:(id)sender {
//if(![popoverController isPopoverVisible]){
NSLog(#"my popover....");
ViewVideoController *videoController = [[[ViewVideoController alloc] initWithNibName:nil bundle:nil] autorelease];
videoController.contentSizeForViewInPopover =CGSizeMake(550, 460);
popoverController = [[UIPopoverController alloc]
initWithContentViewController:videoController];
popoverController.delegate = self;
[videoController release];
popViewBtnFrame = CGRectMake(299, 357, 63, 42);
[popoverController presentPopoverFromRect:popViewBtnFrame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
if (self.popoverController != nil) {
[self.popoverController dismissPopoverAnimated:YES];
//[self.popoverController release];
NSLog(#" if loop popover dismissed");
ViewVideoController *videoController = [[ViewVideoController alloc] initWithNibName:#"ViewVideoController" bundle:nil];
[videoController unloading];
}
NSLog(#"popover dismissed");
}
on button press player start playing in popoverController.
#implementation ViewVideoController
- (void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"AlphabetTrain" ofType:#"mov"];
NSURL *url = [NSURL fileURLWithPath:path];
player = [[MPMoviePlayerController alloc] initWithContentURL:url];
//player.movieControlMode = MPMovieControlModeHidden;
player.controlStyle = MPMovieControlStyleDefault;
player.view.frame = CGRectMake(75.0f, 80.0f, 400.0f, 300.0f);
[[self view] setCenter:CGPointMake( [[self view] bounds].size.width / 2, [[self view] bounds].size.height / 2)];
[self.view addSubview:player.view];
[player play];
//[player release];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[super viewDidLoad];
}
- (void)myMovieFinishedCallback:(NSNotification*)aNotification {
MPMoviePlayerController* player1 = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player1];
NSLog(#"stop player");
[player stop];
}
- (void)unloading { //this function called in firstviewcontroller to stop player on dismiss
NSLog(#"unloading player");
//[player endSeeking];
[self.player stop];
}
When I dismiss ViewVideoController player keeps on playing. Is there any way to stop/release player on dismiss of ViewVideoController
You can use delegate method
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
[moviePlayer stop];
}

MPMoviePlayer Bad-Access error after playing video

I´ve created an new ViewController (only with the .h and .m file) and added that code to play a video. After the video has finished, i get a "Exe_bad_access" error.
Error message when adding "NSZombieEnabled=true" to the excecutable as a argument:
"TestPlayingVideo[654:207]
-[MPMoviePlayerController stop]: message sent to deallocated instance
0x63042d0"
Whats wrong with that? How can i do correct memory management when playing video?
#import "TestPlayingVideoViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#implementation TestPlayingVideoViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor darkGrayColor]];
UIButton* btn = [[UIButton alloc] initWithFrame:CGRectMake(50 , 50, 200, 25)];
[btn setTitle:#"press me" forState:UIControlStateNormal];
[btn addTarget:self action:#selector(action:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[btn release];
}
- (void)action:(id)sender
{
NSLog(#"UIButton was clicked");
NSString *url = [[NSBundle mainBundle] pathForResource:#"mymovie" ofType:#"m4v"];
MPMoviePlayerViewController* moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:url] ];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackComplete:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayerController.moviePlayer];
[moviePlayerController.moviePlayer play];
//[self.view addSubview:moviePlayerController.view];
[self presentMoviePlayerViewControllerAnimated:moviePlayerController];
}
- (void) moviePlayBackComplete:(NSNotification*) notification {
MPMoviePlayerController* player = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:player];
[self dismissMoviePlayerViewControllerAnimated];
[player stop];
//[self.view removeFromSuperView];
[player release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
There's a lot of confusion here over what you're releasing: for example, here's your main alloc of your movie player:
MPMoviePlayerViewController* moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:url] ];
But what you are releasing isn't this moviePlayerController - you're only releasing the .moviePlayer property of your MPMoviePlayerController. Notice when you create your NSNotification you're passing moviePlayerController.moviePlayer, not simply moviePlayerController.
So you're not releasing your moviePlayerController, you're in fact attempting to release a property of that object. Which you shouldn't do - you should release the object, and let it worry about releasing its properties.