Как использовать AVFoundation для обрезки видео

Я пытаюсь использовать AVFoundation для обрезки записываемых видео. Допустим, я создаю AVCaptureVideoPreviewLayer и устанавливаю размер кадра 300x300.

AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer     layerWithSession:session];
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
captureVideoPreviewLayer.delegate = self;
captureVideoPreviewLayer.frame = CGRectMake(0,0, 300, 300);
[previewView.layer addSublayer:captureVideoPreviewLayer];

Пользователь видит видео обрезанным. Я хотел бы сохранить видео именно так, как его просматривает пользователь. При использовании AVCaptureMovieFileOutput видео явно сохраняется без обрезки. Я рассматривал возможность использования AVCaptureVideoDataOutput для перехвата кадров и их самостоятельной обрезки, но мне было интересно, есть ли более эффективный способ сделать это, возможно, с помощью AVExportSession и использования AVVideoComposition.

Любое руководство будет оценено.


person haider    schedule 04.03.2011    source источник
comment
Удалось ли вам добиться того, чтобы результат выглядел так же четко, как слой предварительного просмотра? Это была проблема, соответствующая резкости AVLayerVideoGravityResizeAspectFill.   -  person Crashalot    schedule 09.02.2016


Ответы (2)


Что-то вроде этого. 99% этого кода просто настраивает его для выполнения пользовательского CGAffineTransform, а затем сохраняет результат.

Я предполагаю, что вы хотите, чтобы обрезанное видео занимало полный размер/ширину вывода, так что, например, Scale Affine является правильным решением (вы увеличиваете масштаб видео, создавая эффект обрезки + изменения размера).

AVAsset* asset = // your input

AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

AVMutableVideoComposition* videoComposition = [[AVMutableVideoComposition videoComposition]retain];
videoComposition.renderSize = CGSizeMake(320, 240);
videoComposition.frameDuration = CMTimeMake(1, 30);

AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30) );

AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
CGAffineTransform finalTransform = // setup a transform that grows the video, effectively causing a crop
    [transformer setTransform:finalTransform atTime:kCMTimeZero];
    instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];

exporter = [[AVAssetExportSession alloc] initWithAsset:saveComposition presetName:AVAssetExportPresetHighestQuality] ;
exporter.videoComposition = videoComposition;
exporter.outputURL=url3;
exporter.outputFileType=AVFileTypeQuickTimeMovie;

[exporter exportAsynchronouslyWithCompletionHandler:^(void){}];
person Adam    schedule 08.03.2011
comment
Адам, спасибо за пост. Я действительно сделал именно это и собирался опубликовать ответ, но вы опередили меня! Спасибо за помощь независимо ... Я думаю, что другие обязательно выиграют. - person haider; 09.03.2011
comment
Не могли бы вы подробнее рассказать о получении входных данных AVAsset. Вы запускаете это в файле фильма после его сохранения с помощью AVCaptureMovieFileOutput? - person Stephen Handley; 08.03.2012
comment
AVAsset — это универсальный класс Apple, который упаковывает любые входные данные, которые вы можете предоставить AVFoundation. Внезапно вы захотите взглянуть на различные подклассы, существующие в AVF (перейдите на любую из страниц документации Apple для AVF и щелкните любую ссылку на ссылку на класс, и вы получите полный список) — они re все названы AV [что-то] Актив IIRC. - person Adam; 08.03.2012
comment
Кроме того, IIRC кое-что расширяет AVAsset для удобства, хотя это не очевидно, если вы не посмотрите документы. По сути, все, что предположительно представляет собой актив ... в значительной степени расширяет AVAsset. - person Adam; 08.03.2012
comment
Привет, Адам, я использую тот же код, получаю звук, но не отображаю видео. Можете ли вы сказать мне какой-либо дополнительный код для обрезки видео? - person Vishal Khatri; 07.01.2014
comment
Можем ли мы получить пример преобразования, которое увеличивает видео, эффективно вызывая обрезку? - person etayluz; 17.07.2015
comment
Для чего используется композицияVideoTrack? Этот код не компилируется и выдает много предупреждений. - person etayluz; 17.07.2015
comment
@etayluz вот сообщение, помогающее увеличить/обрезать видео: stackoverflow. ком/вопросы/3968879/ - person Crashalot; 09.02.2016
comment
@Adam Можете ли вы привести рабочий пример. Демонстрация этого в Swift действительно спасла бы жизнь - person Ankit Kumar Gupta; 13.04.2017
comment
@AnkitKumarGupta У вас есть рабочий пример - вы ответили на него. Если у вас другая проблема, задайте новый вопрос. Вот для чего этот сайт. - person Adam; 18.04.2017
comment
@ Адам Спасибо, я смог создать это для себя. Вы можете посмотреть и сказать мне, можно ли это улучшить или что-то, что я делаю неправильно. › github.com/ankit-betterbutter/CustomCamera - person Ankit Kumar Gupta; 18.04.2017

iOS7 добавила специальную инструкцию слоя только для обрезки.

videolayerInstruction setCropRectangle:atTime:

_Майк

person nibeck    schedule 25.11.2013
comment
Это не дает ожидаемых результатов. к вашему сведению. Этот параметр обрезает прямоугольник из исходного размера видео в пикселях. Не связано с размером экрана на устройстве. - person Maxim Veksler; 08.05.2014
comment
@nibeck, не могли бы вы включить блок кода, демонстрирующий, как это использовать? - person etayluz; 17.07.2015
comment
Я попробовал это. Но не работал для меня. Пришлось переключиться обратно на преобразование перевода. - person Sreeraj; 03.08.2015