AVPlayerLayer становится пустым после нескольких вызовов presentModalView / dismissModalView - PullRequest
6 голосов
/ 13 декабря 2011

У меня есть приложение для воспроизведения видео, которое ничего не отображает в AVPlayerLayer после многократного представления и скрытия модального представления, в котором оно содержится. Если я отклоняю модальное представление, когда это происходит, следующая загрузка обычно отображается нормально (? !!) .Проблема с черным экраном возникает примерно в 20% случаев.

Я строю AVMutableComposition для создания AVPlayerItem, но эта ошибка возникает, даже если задействован только один образец.

Проблема также может быть воспроизведена с большим количеством приложений, включающих и выключающих музыку.Я включаю элементы управления музыкой в ​​свое приложение (вместе с простым представлением, отображающим текущую воспроизводимую дорожку iTunes).

Это происходит только в iOS 4. Раньше это происходило и в iOS 5, но когда я начиналперерабатывая представление, содержащее AVPlayerLayer, все работало нормально.Единственные вещи, которые я не перерабатываю, это AVPlayer и соответствующий AVPlayerItem.

Вот как я загружаю ресурсы и собираю игрока:

- (void)loadAssetsFromFiles:(id)sender {
    NSLog(@"loadAssetsFromFiles called");

    assert ([assetURL2clipID count] > 0);

    self.isWaitingToLoadAssets = NO;

    composition = [AVMutableComposition new];
    videoComposition = [AVMutableVideoComposition new];
    [self releaseAssets];

    //We're going to add this asset to a composition, so we'll need to have random access available
    //WARNING: This can cause slow initial loading, so consider loading files later and as needed.
    NSDictionary *assetOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
                                                        forKey:AVURLAssetPreferPreciseDurationAndTimingKey];

    //iterate through the asset urls we know we need to load
    for (NSURL *fileURL in [assetURL2clipID allKeys])
    {
        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:assetOptions];
        assert(asset);
        //index assets by clipID
        [assets setObject:asset forKey:[assetURL2clipID objectForKey:fileURL]];


        NSString *tracksKey = @"tracks";

        [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracksKey] completionHandler:
         ^{
             NSLog(@"an asset completed loading values for keys.");

             NSLog(@"Tracks loaded:");
             [asset.tracks enumerateObjectsUsingBlock:
                ^(AVAssetTrack *obj, NSUInteger index, BOOL *stop)
                {
                    NSLog(@"\n  mediaType: %@\n trackID: %d\n", obj.mediaType, obj.trackID);
                }];

             NSArray *metadata = [asset commonMetadata];
             for ( AVMetadataItem* item in metadata ) {
                 NSString *key = [item commonKey];
                 NSString *value = [item stringValue];
                 NSLog(@"   metadata key = %@, value = %@", key, value);
             }

             if (!viewIsActive)
             {
                 NSLog(@"An asset finished loading while the player view was inactive!  Did you make sure cancelLoading called on this asset?");
             }

             // Completion handler block.
             NSError *error = nil;

             AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error];



             if (status == AVKeyValueStatusLoaded && error == nil) {

                 //if we've loaded all of our assets, it's time to build the composition and prepare the player!
                 loadedAssets++;
                 if (loadedAssets == [assets count])
                 {

                     CGSize videoSize = [asset naturalSize];
                     //every video composition needs these set
                     videoComposition.renderSize = videoSize;
                     videoComposition.frameDuration = CMTimeMake(1, 30); // 30 fps.  TODO: Set this to the framerate of one of the assets

                     //using the assets we've already got
                    [self buildCompositions];

                    self.playerItem = [AVPlayerItem playerItemWithAsset:composition];
                    self.playerItem.videoComposition = videoComposition;

                    //TODO: Adding observer stuff should be on the main thread to prevent a partial notification from happening
                    [playerItem addObserver:self forKeyPath:@"status"

                                 options:0 context:&ItemStatusContext];

                    [[NSNotificationCenter defaultCenter] addObserver:self

                                                          selector:@selector(playerItemDidReachEnd:)

                                                              name:AVPlayerItemDidPlayToEndTimeNotification

                                                            object:playerItem];

                    self.player = [AVPlayer playerWithPlayerItem:playerItem];

                    [playerView setPlayer:player];


                    [self.player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
                    self.isObservingPlayerStatus = YES;
                 }

             } else if (error != nil) {
                 // Deal with the error appropriately.
                 NSLog(@"WARNING: An asset's tracks were not loaded, so the composition cannot be completed. Error:\n%@\nstatus of asset: %d", [error localizedDescription], status);

             }
             else
             {
                 //There was no error but we don't know what the problem was.
                 NSLog(@"WARNING: An asset's tracks were not loaded, so the composition cannot be completed. No error was reported.\nstatus of asset: %d", status);
             }

         }];
    }
}

Эта функция [self buildCompositions]Вы видите, что создает AVVideoComposition для изменения прозрачности, но я попытался обойти его и получить ту же проблему.

При профилировании программы CoreAnimation сообщает о частоте кадров ~ 45 FPS, когда все работает правильно, и 0-4 FPS, когда пустой экран поднимает свою предположительно уродливую голову.

У этого парня, похоже, была похожая проблема, но для меня переработка просмотров действительно исправляла только вещи для iOS 5: Воспроизведение множества разных видеона iphone с помощью AVPlayer

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...