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.
Related
i want to play video of 4 second in app after default black image is launched what can i do? please help me
my code is below
-(void)viewWillAppear:(BOOL)animated
{
NSString* moviePath = [[NSBundle mainBundle] pathForResource:#"intro_anim" ofType:#"mov"];
NSURL* movieURL = [NSURL fileURLWithPath:moviePath];
NSLog(#"%#",movieURL );
playerCtrl = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[playerCtrl prepareToPlay];
playerCtrl.scalingMode = MPMovieScalingModeFill;
playerCtrl.controlStyle = MPMovieControlStyleNone;
playerCtrl.view.frame = CGRectMake(0, 0, 480, 320);
[playerCtrl.view setCenter:CGPointMake(240, 160)];
[playerCtrl.view setFrame:CGRectMake(0, 0, 480, 320)];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[playerCtrl play];
[self presentMoviePlayerViewControllerAnimated:playerCtrl.view];
[self.view addSubview:playerCtrl.view];
}
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface ViewController : UIViewController
{
NSString *url;
UIButton *btnvideo;
UIButton *btnaudio;
MPMoviePlayerController *player;
MPMoviePlayerController *Player;
NSArray *arr;
}
#property(nonatomic,retain)IBOutlet UIButton *btnvideo;
#property(nonatomic,retain)IBOutlet UIButton *btnaudio;
-(void) moviefinished:(NSNotification *)anotification;
-(void) Audiofinished:(NSNotification *)bnotification;
-(IBAction)PlayAudio:(id)sender;
-(IBAction)PlayVideo:(id)sender;
#import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h>
-(IBAction)PlayVideo:(id)sender
{
url=[[NSBundle mainBundle]pathForResource:#"nfc" ofType:#"mp4"];
player=[[MPMoviePlayerController alloc]initWithContentURL:[NSURL fileURLWithPath:url]];
player.view.frame=CGRectMake(0, 0, 320, 300);
[self.view addSubview:player.view];
[player play];
}
-(IBAction)PlayAudio:(id)sender
{
[player release];
url=[[NSBundle mainBundle]pathForResource:#"bgm" ofType:#"mp3"];
Player=[[MPMoviePlayerController alloc]initWithContentURL:[NSURL fileURLWithPath:url]];
Player.view.frame=CGRectMake(0, 0, 320, 300);
[self.view addSubview:Player.view];
[Player play];
}
-(void) moviefinished:(NSNotification *)anotification
{
player=[anotification object];
[[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:player];
[player autorelease];
}
-(void) Audiofinished:(NSNotification *)bnotification
{
player=[bnotification object];
[[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:Player];
[Player autorelease];
}
-(void)presentMoviePlayerViewControllerAnimated:(MPMoviePlayerViewController *)moviePlayerViewController
{
[player setControlStyle:MPMovieScalingModeAspectFit];
}
Note- please mind it to connect playaudio button action to
Insted of a default image use a view controller as splash and push the "first viewcontroller" using timer. You can do whatever you want on your "splash view controller."
I have been able to successfully play a video on start of the app by calling a function that plays the video in the viewDidLoad method. But on doing so, i am unable to see the "Done" button. The "Done" button only seems to appear if i call that same function with the help of a button. I am posting the code below. How will I make this done appear by calling the same function in the viewDidLoad method? What have i been doing wrong? Thank you!
in my viewcontroller.m file
- (void)viewDidLoad
{
[super viewDidLoad];
[self playMedia];
}
- (void) playMedia {
//hide status bar first
[[UIApplication sharedApplication] setStatusBarHidden:YES];
//resets again in playMediaFinished
movieFile = [[NSBundle mainBundle] pathForResource:#"sec" ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath: movieFile];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playMediaFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
[moviePlayer setFullscreen:NO animated:YES];
[self.view addSubview:moviePlayer.view];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
CGAffineTransform transform = self.view.transform;
[moviePlayer.view setFrame:CGRectMake(0, 0, 480, 320)];
moviePlayer.shouldAutoplay = YES;
NSLog(#"Should be playing Movie");
}
- (void) playMediaFinished: (NSNotification*) theNotification {
moviePlayer = [theNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
if ([moviePlayer
respondsToSelector:#selector(setFullscreen:animated:)])
{
[moviePlayer.view removeFromSuperview];
[playerView removeFromSuperview];
//reset status bar
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
NSLog(#"Should be DONE playing Movie");
}
Try doing this using viewDidAppear instead of viewDidLoad. I'm not surprised starting a video in viewDidLoad is causing unexpected behavior considering you're presenting the video before the main view appears on screen. Keep in mind, the view is done loading before it is actually visible.
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"];
}
Hi Everyone Gud Evening
I have taken a view on which i had to play the video, the video is being played Perfectly, but very rarely i the video is not being appeared on the view, at that time i got a warning in the console like
WARNING: under normal conditions, _fillInQueueWithExtraSpace:ignoreExistingItems: should not be re-entered.
Could some one help me to sort out this problem
Thank You Everyone
I have 2 UIView's in being displayed on the same view, In one view when i start drawing the movieplayer gets started in the bottomProgressView , in the viewcontroller in viewdidload the code is like this
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *url = [[NSBundle mainBundle] pathForResource:#"progres" ofType:#"mp4"];
timeCompletedCnlr = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]] ;
[timeCompletedCnlr.view setFrame:CGRectMake(0,468, 600, 50)];
[timeCompletedCnlr setControlStyle:MPMovieControlStyleNone];
[bottomProgressView addSubview:timeCompletedCnlr.view];
}
When i touch the view that is being to drawn then the below method is called.
- (void)removeGivenWord
{
[bottomToolBar removeFromSuperview];
[self.view addSubview:bottomProgressView];
[timeCompletedCnlr play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(helpVideoFinished:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:timeCompletedCnlr];
UIButton *doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
doneBtn.frame = CGRectMake(601, 940, 167, 43);
[doneBtn setBackgroundImage:[UIImage imageNamed:#"done.png"] forState:UIControlStateNormal];
[doneBtn addTarget:self action:#selector(doneButtonClicked) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:doneBtn];
}
the view on which the video is placed also contains the done button too..
- (void)doneButtonClicked {
[timeCompletedCnlr stop];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(helpVideoFinished:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:timeCompletedCnlr];
}
- (void) helpVideoFinished:(NSNotification*) aNotification {
MPMoviePlayerController *player1 = [aNotification object];
[[NSNotificationCenter defaultCenter]removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player1];
[smoothLineView completed5Sec];
NSLog(#"5sec called");
NSError *error = [[aNotification userInfo] objectForKey:#"error"];
if (error) {
NSLog(#"Did finish with error: %#", error);
}
}
My Problem is the video sometimes it appears and sometime it doesn't come,
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];
}