AVMutableComposition поворачивает видео
Недавно я обнаружил проблему с использованием AVMutableComposition, и я ищу некоторое представление об этом.
Я хочу иметь возможность записывать видео в двух направлениях - влево и вправо. Когда я записываю видео в альбомной ориентации (кнопка справа находится справа), они добавляются в композицию и воспроизводятся в правильной ориентации. Однако, если я записываю его влево влево (главная кнопка слева), эти клипы воспроизводятся вверх ногами.
НО, они воспроизводятся только вверх дном, если они вставлены в композицию. В противном случае они играют в правильной ориентации. Почему композиция меняет направление вращения клипов, снятых в ландшафте? Как я могу это исправить? Любая помощь приветствуется!
Ответы
Ответ 1
Здесь немного проще, если вы просто хотите сохранить оригинальное вращение.
// Grab the source track from AVURLAsset for example.
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].lastObject;
// Grab the composition video track from AVMutableComposition you already made.
AVMutableCompositionTrack *compositionVideoTrack = [composition tracksWithMediaType:AVMediaTypeVideo].lastObject;
// Apply the original transform.
if (assetVideoTrack && compositionVideoTrack) {
[compositionVideoTrack setPreferredTransform:assetVideoTrack.preferredTransform];
}
// Export...
Ответ 2
Решила мою проблему. Наконец, он смог повернуть дорожку и перевести ее в кадр. Работает как шарм.
//setting up the first video based on previous recording
CMTimeRange videoDuration = CMTimeRangeMake(kCMTimeZero, [self.previousRecording duration]);
AVAssetTrack *clipVideoTrack = [[self.previousRecording tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *clipAudioTrack = [[self.previousRecording tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionVideoTrack insertTimeRange:videoDuration ofTrack:clipVideoTrack atTime:nextClipStartTime error:nil];
[compositionAudioTrack insertTimeRange:videoDuration ofTrack:clipAudioTrack atTime:nextClipStartTime error:nil];
//our first track instruction - set up the instruction layer, then check the orientation of the track
//if the track is in landscape-left mode, it needs to be rotated 180 degrees (PI)
AVMutableVideoCompositionLayerInstruction *firstTrackInstruction =
[AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
if([self orientationForTrack:clipVideoTrack] == UIDeviceOrientationLandscapeLeft) {
CGAffineTransform rotation = CGAffineTransformMakeRotation(M_PI);
CGAffineTransform translateToCenter = CGAffineTransformMakeTranslation(640, 480);
CGAffineTransform mixedTransform = CGAffineTransformConcat(rotation, translateToCenter);
[firstTrackInstruction setTransform:mixedTransform atTime:kCMTimeZero];
}
Ответ 3
Я думаю, что ответ наверняка лучший вариант, но он лишь частично правильный. На самом деле, чтобы заставить его работать, нам также нужно отрегулировать размер рендеринга экспорта, высоту и ширину размера естественного размера портретной дорожки.
Я только что протестировал его, и я также цитирую раздел "Руководство по программированию AVFoundation" - "Редактирование", в котором предлагается реализовать то, что на самом деле предлагается в ответ @dizy, но с указанным дополнением:
Все объекты AVAssetTrack имеют свойство preferredTransform, которое содержит информацию о ориентации для этой дорожки актива. Это преобразование применяется всякий раз, когда дорожка актива отображается на экране. В предыдущем коде преобразование инструкций слоя устанавливается на преобразование дорожек актива, чтобы видео в новой композиции отображалось правильно после того, как вы отредактируете его размер рендеринга.
Затем код должен быть таким же (только две строки для добавления):
// Grab the source track from AVURLAsset for example.
AVAssetTrack *assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].lastObject;
// Grab the composition video track from AVMutableComposition you already made.
AVMutableCompositionTrack *compositionVideoTrack = [composition tracksWithMediaType:AVMediaTypeVideo].lastObject;
// Apply the original transform.
if (assetVideoTrack && compositionVideoTrack) {
[compositionVideoTrack setPreferredTransform:assetVideoTrack.preferredTransform];
}
flippedSize = CGSize(compositionVideoTrack.naturalSize.height, compositionVideoTrack.naturalSize.width);
composition.renderSize = flippedSize;
// Export..