AVMutableComposition - scaleTimeRange вызывает быстрое движение видео с высокой скоростью передачи данных

Я использую scaleTimeRange:toDuration: для создания эффекта быстрого движения, в 10 раз превышающего исходную скорость видео. Однако я заметил, что видео с более высокой скоростью передачи данных (скажем, 20 Мбит / с и выше) начинает заикаться при воспроизведении через AVPlayer на скорости, в 4 раза превышающей нормальную скорость, что достаточно для сбоя AVPlayerLayer (исчезает), если он работает некоторое время.,

Код.

//initialize the player
self.player = [[AVPlayer alloc] init];

//load up the asset
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[[NSBundle mainBundle] URLForResource:@"sample-video" withExtension:@"mov"] options:nil];

[asset loadValuesAsynchronouslyForKeys:@[@"playable", @"hasProtectedContent", @"tracks"] completionHandler:
 ^{
     AVMutableComposition *composition = [AVMutableComposition composition];
     AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];

     // composition set to play at 60fps
     videoComposition.frameDuration = CMTimeMake(1,60);

     //add video track to composition
     AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

     //1080p composition
     CGSize renderSize = CGSizeMake(1920.0, 1080.0);
     CMTime currentTime = kCMTimeZero;
     CGFloat scale = 1.0;
     AVAssetTrack *assetTrack = nil;

     assetTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;

     [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:assetTrack  atTime:currentTime error:nil];


     CMTimeRange scaleTimeRange = CMTimeRangeMake(currentTime, asset.duration);

     //Speed it up to 8x.
     CMTime scaledDuration = CMTimeMultiplyByFloat64(asset.duration,1.0/8.0);

     [videoTrack scaleTimeRange:scaleTimeRange toDuration:scaledDuration];

     AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];

     //ensure video is scaled up/down to match the composition
     scale = renderSize.width/assetTrack.naturalSize.width;
     [layerInstruction setTransform:CGAffineTransformMakeScale(scale, scale) atTime:currentTime];


     AVMutableVideoCompositionInstruction *videoInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
     videoInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration);
     videoInstruction.layerInstructions = @[ layerInstruction];

     videoComposition.instructions = @[videoInstruction];
     videoComposition.renderSize = renderSize;

     //pass the stuff to AVPlayer for playback
     self.playerItem = [AVPlayerItem playerItemWithAsset:composition];
     self.playerItem.videoComposition = videoComposition;
     [self.player replaceCurrentItemWithPlayerItem:self.playerItem];

     //playerView is a custom view with AVPlayerLayer, picked up from https://developer.apple.com/library/mac/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html#//apple_ref/doc/uid/TP40010188-CH3-SW11

     [self.playerView setPlayer:self.player];

     //call [self.player play] when ready.


 }];

Некоторые заметки:

  • Все тесты сделаны на iPhone 6
  • Я намеренно не добавляю никаких звуковых дорожек, чтобы исключить возможность воспроизведения звука здесь.
  • Нормальное видео с битрейтом (в среднем 16 Мбит / с) воспроизводится нормально в 10 раз
  • Такой же код композиции обеспечивает плавное воспроизведение в приложении OSX
  • Заикание более очевидно с более высокими битрейтами.
  • Все тестируемые видео - 1080p 60fps
  • Видео с высоким битрейтом ведет себя хорошо, если его открыть и экспортировать в 1080, чтобы снизить скорость передачи и поддерживать FPS.
  • Нет никакого рендеринга / экспорта видео.

Кто-нибудь еще сталкивался с этим и знает способ?

0 ответов

Другие вопросы по тегам