iPhone SDK. Можно ли вращать видео в AVplayer с помощью AVURLlAsset / AVMutableComposition?

У меня есть простой вид для редактирования видео, который использует AVPlayer. Я создаю AVMutableComposition, используя один или несколько AVURLAsset. Все работает нормально, но видео всегда поворачивается на 90 градусов. т.е. если исходное видео было снято в портретном режиме. AVPlayer показывает его в ландшафтном режиме и наоборот. Я просмотрел документацию и "забил" ее до смерти и не могу найти решение. Может я смотрю не в тех местах.

Кто-нибудь может помочь?

Заранее спасибо;

Жан-Пьер

2 ответа

Насколько я понимаю, у вас есть некоторые проблемы с ориентацией, например, Портретное видео находится в альбомном режиме, а иногда видео переворачивается с ног на голову. Это связано с ориентацией AVAsset по умолчанию. Все видеофайлы и файлы изображений, записанные с помощью приложения камеры iPhone по умолчанию, имеют видеокадр, установленный на альбомную ориентацию, и поэтому носитель сохраняется в альбомной ориентации. У AVAsset есть свойство lovelyTransform, которое содержит информацию об ориентации мультимедиа, и оно применяется к файлу мультимедиа всякий раз, когда вы просматриваете его с помощью приложения "Фотографии" или QuickTime. Вы можете легко исправить это, применив необходимые преобразования к вашим объектам AVAsset. Но поскольку ваши два видеофайла могут иметь разную ориентацию, вам нужно использовать два отдельных экземпляра AVMutableCompositionTrack вместо одного (предположим), как вы это делали изначально. Создайте две видеодорожки AVMutableCompositionTrack Поскольку у вас теперь есть два отдельных экземпляра AVMutableCompositionTrack, вам нужно применить AVMutableVideoCompositionLayerInstruction к каждой дорожке, чтобы исправить ориентацию. Так что добавьте следующий код

    //  Create AVMutableVideoCompositionInstruction
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeAdd(firstAsset.duration, secondAsset.duration));
// Create an AVMutableVideoCompositionLayerInstruction for the first track
AVMutableVideoCompositionLayerInstruction *firstlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:firstTrack];
AVAssetTrack *firstAssetTrack = [[firstAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
UIImageOrientation firstAssetOrientation_  = UIImageOrientationUp;
BOOL isFirstAssetPortrait_  = NO;
CGAffineTransform firstTransform = firstAssetTrack.preferredTransform;
if (firstTransform.a == 0 && firstTransform.b == 1.0 && firstTransform.c == -1.0 && firstTransform.d == 0) {
    firstAssetOrientation_ = UIImageOrientationRight; 
    isFirstAssetPortrait_ = YES;
}
if (firstTransform.a == 0 && firstTransform.b == -1.0 && firstTransform.c == 1.0 && firstTransform.d == 0) {
    firstAssetOrientation_ =  UIImageOrientationLeft; 
    isFirstAssetPortrait_ = YES;
}
if (firstTransform.a == 1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == 1.0) {
    firstAssetOrientation_ =  UIImageOrientationUp;
}
if (firstTransform.a == -1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == -1.0) {
    firstAssetOrientation_ = UIImageOrientationDown;
}
[firstlayerInstruction setTransform:firstAsset.preferredTransform atTime:kCMTimeZero];
[firstlayerInstruction setOpacity:0.0 atTime:firstAsset.duration];
//  Create an AVMutableVideoCompositionLayerInstruction for the second track
AVMutableVideoCompositionLayerInstruction *secondlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:secondTrack];
AVAssetTrack *secondAssetTrack = [[secondAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
UIImageOrientation secondAssetOrientation_  = UIImageOrientationUp;
BOOL isSecondAssetPortrait_  = NO;
CGAffineTransform secondTransform = secondAssetTrack.preferredTransform;
if (secondTransform.a == 0 && secondTransform.b == 1.0 && secondTransform.c == -1.0 && secondTransform.d == 0) {
    secondAssetOrientation_= UIImageOrientationRight; 
    isSecondAssetPortrait_ = YES;
}
if (secondTransform.a == 0 && secondTransform.b == -1.0 && secondTransform.c == 1.0 && secondTransform.d == 0) {
    secondAssetOrientation_ =  UIImageOrientationLeft; 
    isSecondAssetPortrait_ = YES;
}
if (secondTransform.a == 1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == 1.0) {
    secondAssetOrientation_ =  UIImageOrientationUp;
}
if (secondTransform.a == -1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == -1.0) {
    secondAssetOrientation_ = UIImageOrientationDown;
}
[secondlayerInstruction setTransform:secondAsset.preferredTransform atTime:firstAsset.duration];
}

наконец добавьте инструкции, это просто исправление ориентации, примененное ко второму треку.

    mainInstruction.layerInstructions = [NSArray arrayWithObjects:firstlayerInstruction, secondlayerInstruction,nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);

CGSize naturalSizeFirst, naturalSizeSecond;
if(isFirstAssetPortrait_){
    naturalSizeFirst = CGSizeMake(FirstAssetTrack.naturalSize.height, FirstAssetTrack.naturalSize.width);
} else {
    naturalSizeFirst = FirstAssetTrack.naturalSize;
}
if(isSecondAssetPortrait_){
    naturalSizeSecond = CGSizeMake(SecondAssetTrack.naturalSize.height, SecondAssetTrack.naturalSize.width);
} else {
    naturalSizeSecond = SecondAssetTrack.naturalSize;
}

float renderWidth, renderHeight;
if(naturalSizeFirst.width > naturalSizeSecond.width) {
    renderWidth = naturalSizeFirst.width;
} else {
    renderWidth = naturalSizeSecond.width;
}
if(naturalSizeFirst.height > naturalSizeSecond.height) {
    renderHeight = naturalSizeFirst.height;
} else {
    renderHeight = naturalSizeSecond.height;
}
MainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight);

надеюсь это поможет

Не имея кода для анализа, трудно понять, что происходит... Но, скорее всего, ваша проблема вызвана тем, что вы теряете ценность своего preferredTransform имущество.

Все AVAssetTrack объекты имеют preferredTransform свойство, которое используется, чтобы указать, следует ли поворачивать видео или нет. Если вы создаете новый AVMutableAssetTrack Для объектов может потребоваться установить значение этого свойства, чтобы видео оставалось в заданной ориентации.

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