- iPhone development mpmovieplayer crashing
- *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An AVPlayerItem cannot be associated with more than one instance of AVPlayer'
- *** First throw call stack:
- (0x380da8bf 0x37c261e5 0x30acbcb5 0x30abc1f7 0x30ac3bf3 0x30c93d55 0x30c95f7b 0x380ad2dd 0x380304dd 0x380303a5 0x37e07fcd 0x31bb0743 0x25e5 0x257c)
- MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
- if (player) {
- [self setMoviePlayerController:player];
- [self installMovieNotificationObservers];
- [player setContentURL:movieURL];
- [player setMovieSourceType:sourceType];
- [self applyUserSettingsToMoviePlayer];
- [self.view addSubview:self.backgroundView];
- [player.view setFrame:self.view.bounds];
- [player.view setBackgroundColor = [UIColor blackColor];
- [self.view addSubview:player.view];
- }
- [[self moviePlayerController] stop];
- MPMoviePlayerController *player = [self moviePlayerController];
- [player.view removeFromSuperview];
- [self removeMovieNotificationHandlers];
- [self setMoviePlayerController:nil];
- @property (strong, nonatomic) MPMoviePlayerController * moviePlayerController;
- self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
- // MoviePlayer.h
- #import <Foundation/Foundation.h>
- #import <MediaPlayer/MediaPlayer.h>
- #import "Logger.h"
- @class MoviePlayerView;
- @interface MoviePlayer : NSObject
- {
- @private
- MPMoviePlayerController *controller;
- MoviePlayerView *currentView;
- }
- @property (nonatomic, readonly) MPMoviePlayerController *controller;
- +(MoviePlayer *) instance;
- -(void) playMovie:(NSURL*)movieURL onView:(MoviePlayerView *)view;
- -(void) stopMovie;
- @end
- // MoviePlayer.m
- #import "MoviePlayer.h"
- #import "MoviePlayerView.h"
- @implementation MoviePlayer
- @synthesize controller;
- static MoviePlayer *player = nil;
- #pragma mark Singleton management
- +(MoviePlayer *) instance
- {
- @synchronized([MoviePlayer class])
- {
- if (player == nil)
- {
- player = [[super allocWithZone:NULL] init];
- player->controller = [[MPMoviePlayerController alloc] init];
- player->controller.shouldAutoplay = NO;
- player->controller.scalingMode = MPMovieScalingModeAspectFit;
- player->currentView = nil;
- }
- return player;
- }
- }
- +(id) allocWithZone:(NSZone *)zone
- {
- return [[self instance] retain];
- }
- -(id) copyWithZone:(NSZone *)zone
- {
- return self;
- }
- -(id) retain
- {
- return self;
- }
- -(NSUInteger) retainCount
- {
- return NSUIntegerMax;
- }
- -(oneway void) release
- {
- // singleton will never be released
- }
- -(id) autorelease
- {
- return self;
- }
- #pragma mark MoviePlayer implementations
- -(void) stopMovie
- {
- @synchronized(self)
- {
- if (controller.view.superview)
- {
- [controller.view removeFromSuperview];
- }
- if (controller.playbackState != MPMoviePlaybackStateStopped)
- {
- [controller pause];
- [controller stop];
- }
- if (currentView)
- {
- NSNotificationCenter *ntfc = [NSNotificationCenter defaultCenter];
- [ntfc removeObserver:currentView name:MPMoviePlayerLoadStateDidChangeNotification object:controller];
- [ntfc removeObserver:currentView name:MPMoviePlayerPlaybackStateDidChangeNotification object:controller];
- currentView = nil;
- }
- }
- }
- -(void) playMovie:(NSURL*)movieURL onView:(MoviePlayerView *)view
- {
- @synchronized(self)
- {
- [self stopMovie];
- currentView = view;
- NSNotificationCenter *ntfc = [NSNotificationCenter defaultCenter];
- [ntfc addObserver:currentView
- selector:@selector(loadStateDidChange:)
- name:MPMoviePlayerLoadStateDidChangeNotification
- object:controller];
- [ntfc addObserver:currentView
- selector:@selector(playbackStateDidChange:)
- name:MPMoviePlayerPlaybackStateDidChangeNotification
- object:controller];
- [controller setContentURL:movieURL];
- controller.view.frame = view.bounds;
- [view addSubview: controller.view];
- [controller play];
- }
- }
- @end
- // MoviePlayerView.h
- #import <UIKit/UIKit.h>
- #import "MoviePlayer.h"
- @interface MoviePlayerView : MediaView
- {
- NSURL *movieURL;
- NSURL *thumbnailURL;
- UIImageView *previewImage;
- UIView *iconView;
- BOOL hasPreviewImage;
- }
- -(id) initWithFrame:(CGRect)frame thumbnailURL:(NSURL *)thumbnail movieURL:(NSURL *)movie;
- -(void) loadStateDidChange:(NSNotification *)ntf;
- -(void) playbackStateDidChange:(NSNotification *)ntf;
- @end
- // MoviePlayerView.m
- #import "MoviePlayerView.h"
- @interface MoviePlayerView()
- -(void) initView;
- -(void) initController;
- -(void) playMovie;
- -(void) setActivityIcon;
- -(void) setMovieIcon:(float)alpha;
- -(void) clearIcon;
- -(CGPoint) centerPoint;
- @end
- @implementation MoviePlayerView
- -(id) initWithFrame:(CGRect)frame thumbnailURL:(NSURL *)thumbnail movieURL:(NSURL *)movie
- {
- self = [super initWithFrame:frame];
- if (self)
- {
- movieURL = [movie retain];
- thumbnailURL = [thumbnail retain];
- [self initView];
- [self initController];
- hasPreviewImage = NO;
- loadingFinished = YES;
- }
- return self;
- }
- -(void) dealloc
- {
- [iconView release];
- [previewImage release];
- [movieURL release];
- [super dealloc];
- }
- -(void)initView
- {
- self.backgroundColor = [UIColor blackColor];
- // add preview image view and icon view
- previewImage = [[UIImageView alloc] initWithFrame:self.bounds];
- [previewImage setContentMode:UIViewContentModeScaleAspectFit];
- UIImage *img = nil;
- if (thumbnailURL)
- {
- img = [ImageUtils loadImageFromURL:thumbnailURL];
- if (img)
- {
- previewImage.image = img;
- hasPreviewImage = YES;
- }
- }
- [self addSubview:previewImage];
- [self setMovieIcon:(hasPreviewImage ? 0.8f : 0.3f)];
- }
- -(void)initController
- {
- UITapGestureRecognizer *rec = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(playMovie)];
- [self addGestureRecognizer:rec];
- [rec release];
- }
- -(void)playMovie
- {
- [[MoviePlayer instance] playMovie:movieURL onView:self];
- [self setActivityIcon];
- }
- -(void) loadStateDidChange:(NSNotification *)ntf
- {
- MPMoviePlayerController *controller = [ntf object];
- switch (controller.loadState)
- {
- case MPMovieLoadStatePlayable:
- {
- [self clearIcon];
- [controller setFullscreen:YES animated:YES];
- break;
- }
- case MPMovieLoadStateStalled:
- {
- [self setActivityIcon];
- break;
- }
- default:
- {
- break; // nothing to be done
- }
- }
- }
- -(void) playbackStateDidChange:(NSNotification *)ntf
- {
- MPMoviePlayerController *controller = [ntf object];
- switch (controller.playbackState)
- {
- case MPMoviePlaybackStatePlaying:
- {
- [self clearIcon];
- break;
- }
- case MPMoviePlaybackStateStopped:
- {
- [self setMovieIcon:(hasPreviewImage ? 0.8f : 0.3f)];
- break;
- }
- case MPMoviePlaybackStatePaused:
- {
- [self setMovieIcon:0.8f];
- break;
- }
- case MPMoviePlaybackStateInterrupted:
- {
- [self setActivityIcon];
- break;
- }
- default:
- {
- break; // nothing to be done
- }
- }
- }
- -(void) setActivityIcon
- {
- [self clearIcon];
- iconView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
- iconView.center = [self centerPoint];
- [self addSubview:iconView];
- [iconView performSelector:@selector(startAnimating)];
- }
- -(void) setMovieIcon:(float)alpha
- {
- [self clearIcon];
- iconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_movie.png"]];
- iconView.center = [self centerPoint];
- iconView.alpha = alpha;
- [self addSubview:iconView];
- }
- -(void) clearIcon
- {
- if (iconView)
- {
- SEL stop = @selector(stopAnimating);
- if ([iconView respondsToSelector:stop])
- {
- [iconView performSelector:stop];
- }
- [iconView removeFromSuperview];
- [iconView release];
- iconView = nil;
- }
- }
- -(CGPoint) centerPoint
- {
- return CGPointMake(roundf(self.bounds.size.width / 2.0f), roundf(self.bounds.size.height / 2.0f));
- }
- -(void)resize
- {
- for (UIView *view in [self subviews])
- {
- if (view == iconView)
- {
- iconView.center = [self centerPoint];
- continue;
- }
- view.frame = self.bounds;
- }
- [self addCaptionLabel];
- }
- -(void) layoutSubviews
- {
- [super layoutSubviews];
- [self resize];
- }
- @end
- [self.moviePlayerController setContentURL:movieURL];
- - (void) moviePlayBackDidFinish:(NSNotification*)notification
- {
- self.moviePlayer = nil;
- [self initanothermovieplayerandplay];
- }
- - (void) moviePlayBackDidFinish:(NSNotification*)notification
- {
- [UIView animateWithDuration:1
- delay: 0.0
- options: UIViewAnimationOptionCurveEaseIn
- animations:^{
- // one second to fade out the view
- self.moviePlayer.view.alpha = 0.0;
- }
- completion:^(BOOL finished){
- self.moviePlayer = nil;
- [self initanothermovieplayerandplay];
- }
- }