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

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

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

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

Жан-Пьер


person Jean-Pierre Semery    schedule 01.03.2011    source источник
comment
После просмотра сеанса WWDC10 на AVFoundation я считаю, что где-то есть настройка, но мне нужно посмотреть его снова. Я опубликую ответ, когда буду уверен   -  person Jean-Pierre Semery    schedule 06.03.2011
comment
Вы когда-нибудь решали эту проблему? У меня такая же проблема.   -  person Jeremie Weldin    schedule 02.02.2012
comment
Вы решили эту проблему? у меня такая же проблема не знаю что делать   -  person Gaby Fitcal    schedule 18.08.2015


Ответы (2)


насколько я понимаю, у вас есть некоторые проблемы с ориентацией, например, портретное видео в альбомном режиме, а иногда видео переворачиваются вверх ногами. Это связано с ориентацией AVAsset по умолчанию. Во всех файлах фильмов и изображений, записанных с помощью приложения камеры iPhone по умолчанию, видеокадр установлен в ландшафтный режим, поэтому медиафайлы сохраняются в ландшафтном режиме. AVAsset имеет свойство selectedTransform, которое содержит информацию об ориентации мультимедиа, и оно применяется к медиафайлу всякий раз, когда вы просматриваете его с помощью приложения «Фотографии» или 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);

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

person Abhinav Singh    schedule 15.05.2013

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

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

person flainez    schedule 08.10.2012