как управлять ориентацией видео, собранного с помощью AVMutableComposition - PullRequest
7 голосов
/ 14 ноября 2010

Я собираю кучу видеоклипов, снятых на iPhone в портретном режиме. Для их сборки я использую простой подход:

AVURLAsset, чтобы получить различные видео, затем поместить их в AVMutableCompositionTrack и затем поместить в AVMutableComposition, который я экспортирую в файл с AVAssetExportSession

Моя проблема в том, что, когда я прихожу, чтобы отобразить видео в UIWebView, оно появляется в ландшафтном режиме. Однако, если я просматриваю какие-либо из представлений компонентов, они появляются в книжном представлении. Кто-нибудь знает, как разобраться в ориентации. Я попытался возиться с AVMutableComposition naturalSize, меняя ширину и высоту вокруг, но это только заставило моих людей выглядеть короткими и толстыми! (пока на их стороне)

Заранее спасибо за любые мысли / предложения

Tudor

Ответы [ 3 ]

12 голосов
/ 13 сентября 2013

Если все, что вам нужно, это сохранить свою ориентацию видео, вы можете присвоить AVMutableCompositionTrack prefferedTransition значение из AVAssetTrack следующим образом:

AVAssetTrack *videoAssetTrack= [[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject];

AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:videoAssetTrack atTime:kCMTimeZero error:&error];

videoCompositionTrack.preferredTransform = videoAssetTrack.preferredTransform;
12 голосов
/ 08 марта 2011

Настройка видео композиции, которая будет обрабатывать поворот + масштаб:

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* rotator = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]];
CGAffineTransform translateToCenter = CGAffineTransformMakeTranslation( 0,-320);    
CGAffineTransform rotateBy90Degrees = CGAffineTransformMakeRotation( M_PI_2);
CGAffineTransform shrinkWidth = CGAffineTransformMakeScale(0.66, 1); // needed because Apple does a "stretch" by default - really, we should find and undo apple's stretch - I suspect it'll be a CALayer defaultTransform, or UIView property causing this
CGAffineTransform finalTransform = CGAffineTransformConcat( shrinkWidth, CGAffineTransformConcat(translateToCenter, rotateBy90Degrees) );
[rotator setTransform:finalTransform atTime:kCMTimeZero];

instruction.layerInstructions = [NSArray arrayWithObject: rotator];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
9 голосов
/ 13 июля 2012

Вот некоторый код, который регулировал вращение, используя предпочтительное преобразование:

    // our composition, with one video and one audio track
AVMutableComposition* composition = [AVMutableComposition composition];
AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

// loop through all the clips, adding them to our track and inserting composition instructions
NSDictionary* options = @{ AVURLAssetPreferPreciseDurationAndTimingKey: @YES };
CMTime insertionPoint = kCMTimeZero;
NSMutableArray* instructions = [NSMutableArray array];
NSError* error = nil;
for (NSURL* outputFileURL in self.movieFileURLs) {
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:outputFileURL options:options];

    // insert this clip's video track into our composition
    NSArray *videoAssetTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    AVAssetTrack *videoAssetTrack = (videoAssetTracks.count > 0 ? [videoAssetTracks objectAtIndex:0] : nil);
    [videoTrack insertTimeRange:CMTimeRangeFromTimeToTime(kCMTimeZero, asset.duration) ofTrack:videoAssetTrack atTime:insertionPoint error:&error];

    // create a layer instruction at the start of this clip to apply the preferred transform to correct orientation issues
    AVMutableVideoCompositionLayerInstruction *instruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack];
    [instruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];

    // create the composition instructions for the range of this clip
    AVMutableVideoCompositionInstruction * videoTrackInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    videoTrackInstruction.timeRange = CMTimeRangeMake(insertionPoint, asset.duration);
    videoTrackInstruction.layerInstructions = @[instruction];
    [instructions addObject:videoTrackInstruction];

    // insert this clip's audio track into our composition
    NSArray *audioAssetTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *audioAssetTrack = (audioAssetTracks.count > 0 ? [audioAssetTracks objectAtIndex:0] : nil);
    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:audioAssetTrack atTime:insertionPoint error:nil];

    // advance the insertion point to the end of the clip
    insertionPoint = CMTimeAdd(insertionPoint, asset.duration);
}

// create our video composition which will be assigned to the player item
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.instructions = instructions;
videoComposition.frameDuration = CMTimeMake(1, videoTrack.naturalTimeScale);
videoComposition.renderSize = videoTrack.naturalSize;
_videoComposition = videoComposition;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...