Продолжительность видео изменяется после создания и экспорта с использованием AVAssetExportSession - PullRequest
0 голосов
/ 26 сентября 2018

Я пытаюсь обрезать квадратный кадр из видео.Ниже описан процесс

  1. Получить актив видео
  2. Получить видеодорожку из этого ресурса
  3. Создать экземпляр AVMutableComposition с длительностью кадра (30 кадров в секунду) и renderSize (обязательный прямоугольник)
  4. Создать экземпляр AVMutableVideoCompositionInstruction с timeRange (0-asset.duration)
  5. Создать экземпляр LayerInstruction
  6. установить его преобразование, чтобы задать смещение кадра
  7. установить LayerInstruction вИнструкция
  8. Установка Инструкции в экземпляре mutableComposition
  9. Создание экземпляра AVAssetExportSession с указанным выше активом и предустановкой HighestQuality
  10. , установка выходного URL, timeRange и типа выходного файла
  11. Экспортировать асинхронно

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

  1. Если в последнем видео было движение, то будетнет обрезки и выходное видео имеет то же время, что и оригинальное
  2. Если видео статическое,такие, что в видео или в последнем видео нет движения, некоторые статические кадры удаляются, а длина видео становится небольшой
  3. В некоторых случаях, когда в видео много движения, эта продолжительностьувеличивается.

Изменение длительности составляет от 0,1 до 1 секунды.Это может быть очень небольшое изменение, но там, где мне нужен этот процесс, продолжительность видео должна быть точной.

Я добавляю код, если вы хотите углубиться в него.

AVAsset *asset ;
asset = [AVAsset assetWithURL:customURL];


//create an avassetrack with our asset
AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

CMTime originalVideoDur = asset.duration;
float orgDurFloat = (float)originalVideoDur.value / (float)originalVideoDur.timescale;


//create a video composition and preset some settings
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.frameDuration = CMTimeMake(1, 30);

//here we are setting its render size to its height x height (Square)
CGFloat outputWidth = UIScreen.mainScreen.bounds.size.width * UIScreen.mainScreen.scale;
videoComposition.renderSize = CGSizeMake(outputWidth, outputWidth);

//create a video instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);

AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];

CGAffineTransform finalTransform = [self getOutputTransformOfAsset:asset track:clipVideoTrack];
[transformer setTransform:finalTransform atTime:kCMTimeZero];

//add the transformer layer instructions, then add to video composition
instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];

//Create an Export Path to store the cropped video
NSString * documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *exportPath = [documentsPath stringByAppendingFormat:@"/CroppedVideo2.mp4"];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];

//Remove any prevouis videos at that path
[[NSFileManager defaultManager]  removeItemAtURL:exportUrl error:nil];

//Export
exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ;
exporter.videoComposition = videoComposition;
exporter.outputURL = exportUrl;
exporter.outputFileType = AVFileTypeMPEG4;
exporter.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);

[exporter exportAsynchronouslyWithCompletionHandler:^
 {
     dispatch_async(dispatch_get_main_queue(), ^{
         //Call when finished
     });
 }];

Вещи, которые я тестировал и не работал:

  • Изменение пресетов AVAssetExportSession.(Без эффекта, за исключением низкого качества, меньшая разница в длительности, но все же огромная разница)
  • Длительность кадра (меньшая длительность кадра, меньшая разница длительности, длительность 1 кадра дает лучшие результаты с длительностью, но выходное видео не используется)

1 Ответ

0 голосов
/ 26 сентября 2018

Нашел проблему: если честно, это не проблема, это своего рода системная ошибка.Экспортер игнорировал последние статические кадры без причины.в точке, где я устанавливаю преобразование в kCMTimeZero, я добавил новую строку, где я устанавливаю такое же преобразование в конце видео.

[transformer setTransform:finalTransform atTime:asset.duration];

Теперь экспортер не игнорирует последние несколько кадров.

...