Avurlasset viene inizializzato correttamente, ma a volte il suo Avplayerlayer associato rende Black

StackOverflow https://stackoverflow.com/questions/9346347

Domanda

Ho un'applicazione in cui l'utente può selezionare dai file video locali. Quando una di quelle miniature viene spinta, all'utente viene presentata una nuova vista che ha un lettore video personalizzato che ho realizzato che presenta il video.

Questo funziona perfettamente, ma solo a volte. La cosa divertente è che se l'utente seleziona un nuovo video (così viene presentato una nuova vista, inizializza esattamente un nuovo oggetto per lettore video personalizzato) esattamente 5 volte, l'avplayerlayer sottostante che viene utilizzato per presentare le immagini del giocatore rende Black, anche se Sembra che l'asset sottostante si carica ancora correttamente (l'interfaccia del giocatore contiene ancora la durata corretta per il video e così via).

Quando viene inizializzato un nuovo oggetto per lettore multimediale personalizzato (che si verifica quando viene caricato il controller di visualizzazione per i giocatori di media contenente la vista), questa è la parte del metodo iniziale che imposta AvPlayer e l'articolo associato:

    // Start to load the specified asset
    mediaAsset = [[AVURLAsset alloc] initWithURL:contentURL options:nil];

    if (mediaAsset == nil)
        NSLog(@"The media asset is zero!!!");

    // Now we need to asynchronously load in the tracks of the specified asset (like audio and video tracks). We load them asynchronously to avoid having the entire app UI freeze while loading occours
    NSString* keyValueToLoad = @"tracks";

    // When loading the tracks asynchronously we also specify a completionHandler, which is the block of code that should be executed once the loading is either or for some reason failed
    [mediaAsset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:keyValueToLoad
                                                 ] completionHandler:^
     {
         // When this block gets executed we check for potential errors or see if the asset loaded successfully
         NSError* error = nil;

         AVKeyValueStatus trackStatus = [mediaAsset statusOfValueForKey:keyValueToLoad error:&error];

         if (error != nil)
         {
             NSLog(@"Error: %@", error.description);
         }

         //switch (trackStatus) {
             //case AVKeyValueStatusLoaded:
         if (trackStatus == AVKeyValueStatusLoaded)
         {
                 NSLog(@"Did load properly!");
                 mediaItem = [AVPlayerItem playerItemWithAsset:mediaAsset];

                if (mediaItem.error == nil)
                    NSLog(@"Everything went fine!");

                if (mediaItem == nil)
                    NSLog(@"THE MEDIA ITEM WAS NIL");

                 [mediaItem addObserver:self forKeyPath:@"status" options:0 context:&itemStatusContext];

                     mediaContentPlayer = [[AVPlayer alloc] initWithPlayerItem:mediaItem];

                         [mediaContentView setPlayer:mediaContentPlayer];

             //mediaContentView = [AVPlayerLayer playerLayerWithPlayer:mediaContentPlayer];

                [activeModeViewBlocked configurePlaybackSliderWithDuration:mediaItem.duration];

                 originalDuration = mediaItem.duration.value / mediaItem.duration.timescale;

                 // We will subscribe to a timeObserver on the player to check for the current playback time of the movie within a specified interval. Doing so will allow us to frequently update the user interface with correct information
                 playbackTimeObserver = [mediaContentPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 50) queue:dispatch_get_main_queue() usingBlock:^(CMTime time)
                                         {
                                             NSLog(@"TIME UPDATED!");
                                             [activeModeViewBlocked updatePlaybackSlider:time];
                                         }];

                 [self syncUI];
         }

         if (trackStatus == AVKeyValueStatusFailed)
         {
             NSLog(@"Something failed!");
         }

         if (trackStatus == AVKeyValueStatusCancelled)
         {
             NSLog(@"Something was cancelled!");
         }
     }];

Ora se inizializza questo oggetto per lettore multimediale personalizzato 5 volte, inizia sempre a rendere schermi neri.

Qualcuno ha idea del perché questo potrebbe accadere?

È stato utile?

Soluzione

Questo mi ha morso anche io. C'è un limite al numero di giocatori video simultanei che Avfoundation consentirà. Quel numero è quattro (per iOS 4.x, più recentemente il numero sembra essere aumentato. Ad esempio, su iOS 7 ho avuto fino a otto su una schermata senza problemi). Ecco perché sta diventando nero il quinto. Non puoi nemmeno supporre che ne otterrai quattro, poiché altre app potrebbero aver bisogno di una "pipeline di rendering".

Questa API provoca una pipeline di rendering:

+[AVPlayer playerWithPlayerItem:]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top