iPhone udvikling mpmovieplayer nedbrud

Jeg arbejder på en app, der vil lade mig spille forskellige videoer på iPad via fjernadgang med en iPhone. Jeg har været følgende sammen med æbler for eksempel en video-afspiller, men jeg har haft nogle problemer. De videoer, spille fint, og jeg kan få det til at spille fra en række videoer, men at skifte mellem dem et par gange, det vil gå ned, og jeg får det i fejlsøgeren:

*** 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)

Dette er den kode jeg bruger til at skabe den spiller:

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];
}

Og når den aktuelle film er stoppet, jeg bruger:

[[self moviePlayerController] stop];

MPMoviePlayerController *player = [self moviePlayerController];
[player.view removeFromSuperview];

[self removeMovieNotificationHandlers];
[self setMoviePlayerController:nil];

Redigere:
Så Jeg har nu opdaget, at det sker hver gang jeg prøver og skifte en video for 11. gang. underligt! Jeg er næsten at trække mit hår ud.

Jeg havde præcis den samme fejl, når du afspiller en video via AirPlay, og giver den mulighed for at blive skubbet i baggrunden. Lejlighedsvis, når ansøgningen blev bragt tilbage til forgrunden, hvis den udsigt, der indeholder den spiller, var blevet losset, forsøg på at genoptage den app, der styrtede ned med præcis denne fejl.
enhver beslutning endnu? jeg havde den samme fejl i området. min app er en video-app, der indlæser forskellige videoer fra internettet. jeg har flere mpmoviecontrollers aktive på samme tid, men kun én spiller på ethvert givet tidspunkt.
Blot for at tilføje en rynke for dette. Denne fejl – i mit tilfælde i hvert fald, og jeg håber, at i tilfælde af OP – bliver udløst, lige efter et “_serverConnectionDiedNotification” er logget ind. Detaljerne er som følger: Info — meddelelse=Fejl Domain=AVFoundationErrorDomain Kode=-11819 “kan Ikke udføre Handlingen” UserInfo=0x42df3e0 {NSLocalizedRecoverySuggestion=Prøv igen senere., NSLocalizedDescription=Ikke Fuldført Handling}. Startede en dusør! På det herrer!

OriginalForfatteren Jeff B | 2011-11-15

8 svar

  1. 7

    Hvad har løst dette problem for mig var at stoppe den MPMoviePlayerController før du laver den setContentURL.

        MPMoviePlayerController *streamPlayer;
    
        [streamPlayer stop];
        [streamPlayer setContentURL:[NSURL URLWithString:selectedStation]];

    OriginalForfatteren RawMean

  2. 1

    I gennemførelsen du har ovenfor, ARC ikke ved, at MPMoviePlayerController er færdig og har brug for at blive frigivet.

    Definere MPMoviePlayerController i din .h-fil og gøre det tilgængeligt via et @ejendom (og @syntetisere).

    @property (strong, nonatomic) MPMoviePlayerController * moviePlayerController;

    Derefter tage resultatet af din alloc & init og tildele den til at. I. E.

    self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
    selv om jeg har ARC tændt? når jeg forsøge at sætte en udgivelse i det bare siger, at det ikke er tilladt i ARC-funktion. skal jeg bare tænde arc off?
    gah… ARC. Jeg er stadig ved at vænne sig til det. Du har brug for dine forældre (view controller?) til eksplicit at bevare din MPMoviePlayer og derefter ARC vil vide, hvad de skal gøre med det. Jeg vil ændre mit svar til at afspejle dette.
    stadig uden held 🙁 kunne det være, du forsøger at tilføje en video, før den anden er stoppet? det sker kun, når du skifter mellem dem et par gange, indtil dem alt virker ok. jeg startede op interments til at kontrollere for lækager og fandt intet. er der noget andet jeg kan bruge til fejlfinding af dette problem? Jeg har aktiveret NSZombieEnabled men det hjælper ikke, jeg gætte, det er ikke frigive noget thats allerede er blevet frigivet.

    OriginalForfatteren Michael Dautermann

  3. 1

    du skal bare holde moviePlayerController, og hvis du ønsker at spille en anden video, skal du blot bruge

    [self.moviePlayerController setContentURL:movieURL];

    derefter i din anmeldelse tilbagekald:

    - (void) moviePlayBackDidFinish:(NSNotification*)notification
    {
        self.moviePlayer = nil;
        [self initanothermovieplayerandplay];
    }

    og vær venlig ikke at fjerne anmeldelsen handler fra notification center, kun gøre dette i dealloc metoden af VC.

    lad os nu tilføje nogle fade, når filmens leg er gjort:

    - (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];
                     }
    }
    Jeg gør det, men det er ikke nok.
    bemærk afklare!
    Sikker! Udover setContentURL jeg tilføje prepareToPlay, for at auto-play. Hvis jeg ikke sætter forberede… det gør det ikke. De ting er, som @Jeff B sagde, det ikke sker hver gang. Efter et par opkald om, at denne fejl sker.
    jeg har tilføjet noget kode i svar, så lad mig vide det hjælper eller ikke.
    Tak for koden! Men jeg tror, at noget skal være muligt at andre så gør ting lig med nul, og at genskabe det, MPMovie… bør være i stand til at skifte problemfrit fra et videoklip til den anden uden at noget som dette, synes du ikke?

    OriginalForfatteren Allen

  4. 1

    Jeg havde præcis det samme problem.
    Intet var galt med min, og jeg gætter på med din kode 🙂
    Bare en brækket video-fil, der var mit problem.
    Skifter *.mov type, m4a for eksempel fast det. Måske en eller flere af de filer, du spiller, der er beskadiget?
    Prøv at finde ud af, hvilke filer føre til nedbrud og end hvis u kan forsøge at hurtigt fremad baglæns afspilning af en af dem, mens spiller – dette bør føre til nedbrud i enkelte prøver.
    Dette er, hvordan jeg fandt den dårlige filer. Af den måde, alle mine dårlige filer var film .mov lavet med Snapz Pro X 🙂

    Interessante. Jeg vil kontrollere dette.
    Dette synes at være rigtigt. Vi er holdt op med at se ned, efter at fjerne nogle test videoer, etc, der var for tilfældig oprindelse, men en “co-symptom” af styrtet var højt CPU-forbrug, og app ‘ en fryse, når du begynder at spille video. Vi har også løst høj CPU problem, men nu er det ikke helt klart, hvad der forårsagede problemet, og hvad der præcist fjernet det. Vi har lige fyret over det hele, og sandsynligvis fået det. Men en uge mere af test ville bevise, at mindst én af disse metoder fungerer. Desværre har jeg ikke fundet en måde at udvide en dusør. Lad mig se.
    Btw, vi prøvede at spille m3u8 er fra en server, og ikke haft nogen problemer indtil begyndelsen af sidste uge. Videoerne alle var indkøbt som Mp4, alle fra den samme kunde, – derfor meget sandsynligt, at blive registreret, der er kodet med de samme indstillinger. Vi kender til en kendsgerning, de er alle 1080p på omkring 8-10 mbps på et gennemsnit. Måske alle thusly point til indhold problemet ja – siden sidste uge er første gang, vi har uploadet nogle tilfældige videoer til at teste systemet. Og afspilning af video/betjener kode ikke havde ændret sig i de sidste par uger.
    Så dette kunne være tættest på at grunden til, at vi står over for dette problem. Men ikke at have konkret bevis endnu, gør mig tilbageholdende med at lukke bounty nu. En uge efter testen ville være fantastisk. 🙁 Jeg havde læst et sted om at starte flere dusører, men har ikke været i stand til at finde ud af det endnu.
    P. s. CPU-brug fix er den første ændring vi har lavet til afspilning af koden i uger, og det var EFTER, at vi står over for problemet.

    OriginalForfatteren Asen Kasimov

  5. 0

    Ikke sikker på, om det er tilfældet her, men vi havde en masse problemer, fordi MPMoviePlayer er en singleton eller andet sted under kølerhjelmen.
    Det vi gjorde var, at vi implementerede vores egen MoviePlayer indpakning, der kan bruges fra UIView (faktisk har vi præcis en underklasse af UIView MoviePlayerView til at vise film), og sikrer, at der kun er én forekomst af MPMoviePlayerController eksisterer. Koden går som denne (det indeholder nogle særlige ting, vi er nødt til at vise previews/thumbs den måde, vi ønsker osv. du skal rydde op samt nogle release-sætninger):

    // 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
    Min klasse er en singleton i forvejen, så dette bør ikke være det.

    OriginalForfatteren Kai Huppmann

  6. 0
    ...
    player = [[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString:...
    ...

    men jeg havde ikke gav internet forbindelse til telefonen (wi-fi) 🙂

    OriginalForfatteren

  7. 0

    Jeg havde det samme problem. Min løsning er at bruge prepareToPlay:

    MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentOfURL:movieURL];
    
    if (player) {
       [player prepareToPlay];
       //...
    }

    OriginalForfatteren Neiman Aleksei

  8. 0

    Denne fejl ser ud til at blive kastet for masser af forskellige grunde, men grunden til at jeg fandt var, at den MPMoviePlayerController klasse freaks ud, hvis man kalder metoder i en bestemt rækkefølge. Fra en IRC Kanal:

    “tilsyneladende, hvis du ringer prepareToPlay under indstilling af en kilde, type og
    IKKE indstilling af visningen alligevel forårsager dette crash”

    Så jeg løst dette ved blot at sørge for, at jeg kaldte prepareToPlay: SIDSTE (eller næstsidste, de sidste er play:).

    Det er også mærkeligt, fordi min oprindelige kode arbejdede i iOS 5.1, men dette problem pludselig manifesterer sig, da jeg begyndte at bruge iOS 6.0 sdk. Det er muligvis en fejl i MPMoviePlayerController kode, så jeg har tænkt mig at være indgivelse af en radar rapport om det, som at kalde prepareToPlay: før indstilling af visning /indstilling af sourceFileType ikke skal kaste en undtagelse (eller i det mindste en undtagelse, der tilsyneladende har noget at gøre med den faktiske fejl)

    OriginalForfatteren mgrandi

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *