Хобрук: Ваш путь к мастерству в программировании

Странное поведение зависания AVMutableComposition при использовании AVMutableVideoComposition

Я пытаюсь объединить несколько видео, используя AVMutableComposition. Проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я пытаюсь добавить какие-либо AVMutableVideoComposition для выполнения каких-либо инструкций, мое воспроизведение останавливается на AVPlayer с точной продолжительностью 6 секунд.

Еще одна интересная особенность заключается в том, что он отлично воспроизводится, если я воспроизвожу его в приложении «Фото» на iPad после экспорта с использованием того же videoComposition. Так почему же он зависает AVPlayer на 6 секундах?

Код:

AVMutableComposition *mutableComposition = [AVMutableComposition composition];

    AVMutableCompositionTrack *videoCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];

    AVMutableCompositionTrack *audioCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];

    for (AVURLAsset *asset in assets)
    {
            AVAssetTrack *assetTrack;
            assetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
            AVAssetTrack *audioAssetTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;


            NSError *error;
            [videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetTrack.timeRange.duration )
                                                   ofTrack:assetTrack
                                                    atTime:time
                                                     error:&error];

            if (error) {
                NSLog(@"asset url :: %@",assetTrack.asset);
                NSLog(@"Error1 - %@", error.debugDescription);
            }

            [audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAssetTrack.timeRange.duration)
                                               ofTrack:audioAssetTrack
                                                atTime:time
                                                 error:&error];

            if (error) {
                NSLog(@"Error2 - %@", error.debugDescription);
            }

            time = CMTimeAdd(time, assetTrack.timeRange.duration);

            if (CGSizeEqualToSize(size, CGSizeZero)) {
                size = assetTrack.naturalSize;;
            }
        }

        AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
        AVMutableVideoCompositionLayerInstruction *videoTrackLayerInstruction =  [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack];

        mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, time);
        mainInstruction.layerInstructions = [NSArray arrayWithObjects:videoTrackLayerInstruction, nil];
        AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
        mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
        mainCompositionInst.frameDuration = CMTimeMake(1, 30);
        mainCompositionInst.renderSize = size;

        pi = [AVPlayerItem playerItemWithAsset:mutableComposition];
        pi.videoComposition = mainCompositionInst;

Кроме того, я знаю, что проблема в основном videoComposition, потому что если я удалю videoComposition, он будет нормально воспроизводиться на AVPlayer.

ОБНОВЛЕНИЕ 1: я только что обнаружил, что когда он зависает через 6 секунд, если я перетаскиваю ползунок назад или вперед (т. е. использую seekToTime), он снова начинает нормально воспроизводиться без дальнейшего зависания.

Также звук продолжает воспроизводиться нормально, даже когда видео заморожено.

ОБНОВЛЕНИЕ 2: если я просто экспортирую его, используя AVAssetExportSession с тем же AVMutableComposition, и загружу актив из экспортированного видео, он будет работать нормально. Так что когда я играю AVMutableComposition напрямую, возникает проблема.


  • У меня была такая же проблема, повезло? 22.07.2015
  • Снова; это все еще происходит. Может ПОЖАЛУЙСТА, здесь кто-нибудь отреагирует? 24.10.2015
  • @Julian: До сих пор не мог решить эту проблему. Расчет завершился экспортом, что связано с ожиданием. Никакого внимания к проблеме после предложения награды. Продолжайте голосовать и надейтесь, что кто-нибудь в конце концов это заметит. 24.10.2015
  • @ Джулиан Пожалуйста, проверьте мой ответ. 30.10.2015
  • Я только что исправил проблему, примерно 30 минут назад, в любом случае спасибо. На самом деле у меня была другая проблема. Я создал инструкции для дорожки ассетов вместо композиции композиции ... Глупая, но мне все равно потребовалось около 3 недель, чтобы найти правильную комбинацию 30.10.2015

Ответы:


1

Наконец, у меня есть решение, чтобы это исправить.

Вы должны играть после того, как статус playerItem изменится на .ReadyToPlay.

См. Ниже.

func startVideoPlayer() {
    let playerItem = AVPlayerItem(asset: self.composition!)
    playerItem.videoComposition = self.videoComposition!

    let player = AVPlayer(playerItem: playerItem)
    player.actionAtItemEnd = .None

    videoPlayerLayer = AVPlayerLayer(player: player)
    videoPlayerLayer!.frame = self.bounds

    /* add playerItem's observer */
    player.addObserver(self, forKeyPath: "player.currentItem.status", options: .New, context: nil)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerItemDidReachEnd:", name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem);

    self.layer.addSublayer(videoPlayerLayer!)
}

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    if keyPath != nil && keyPath! == "player.currentItem.status" {
        if let newValue = change?[NSKeyValueChangeNewKey] {
            if AVPlayerStatus(rawValue: newValue as! Int) == .ReadyToPlay {
                playVideo() /* play after status is changed to .ReadyToPlay */
            }
        }
    } else {
        super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
    }
}    

func playerItemDidReachEnd(notification: NSNotification) {
    let playerItem = notification.object as! AVPlayerItem
    playerItem.seekToTime(kCMTimeZero)

    playVideo()
} 

func playVideo() {
    videoPlayerLayer?.player!.play()
}       
27.10.2015
Новые материалы

Создание успешной организации по науке о данных
"Рабочие часы" Создание успешной организации по науке о данных Как создать эффективную группу по анализу данных! Введение Это обзорная статья о том, как создать эффективную группу по..

Технологии и проблемы будущей работы
Изучение преимуществ и недостатков технологий в образовании В быстро меняющемся мире технологии являются решающим фактором в формировании будущего работы. Многие отрасли уже были..

Игорь Минар из Google приедет на #ReactiveConf2017
Мы рады сообщить еще одну замечательную новость: один из самых востребованных спикеров приезжает в Братиславу на ReactiveConf 2017 ! Возможно, нет двух других кланов разработчиков с более..

Я собираюсь научить вас Python шаг за шагом
Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..

React on Rails
Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

Что такое гибкие методологии разработки программного обеспечения
Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...