2010-11-13 43 views
7

我正在裝配一大堆在iPhone上縱向模式拍攝的視頻剪輯。組裝它們,我採取簡單的方法如下:如何控制與AVMutableComposition組裝的視頻方向

AVURLAsset得到的不同的視頻,然後順手把這些成AVMutableCompositionTrack,然後把這個放入其中我出口與AVAssetExportSession

提交的AVMutableComposition握住我的問題是當我在UIWebView中顯示視頻時,它出現在橫向模式下。但是,如果我查看它們在縱向視圖中顯示的任何組件視圖。有誰知道如何理清方向。我試着用AVMutableComposition的自然尺寸來改變周圍的寬度和高度,但這只是讓我的人看起來很矮很胖! (而在其側)

預先感謝任何想法/建議

+0

任何人甚至知道如何存儲原始方向? – Tudor 2010-11-16 18:44:25

+0

資產跟蹤中有一個originalTransform屬性,您可以在某些情況下設置該屬性。 – Hunter 2011-03-08 18:40:37

回答

11

安裝視頻組合,將處理旋轉+規模:

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]; 
+0

如果您使用的是前置攝像頭,那麼您還需要想出另一種轉換來鏡像視頻,就像內置的相機應用一樣。 – Hunter 2011-03-08 17:21:49

+0

什麼類的類型是'變壓器'? – 2011-03-19 01:37:33

+0

抱歉 - 複製/粘貼錯誤。該行是不必要的(現在刪除) – Adam 2011-03-19 13:45:32

9

下面是一些代碼,調整使用優選變換的旋轉:

// 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; 
+1

我一直在嘗試在我的應用程序中使用這段代碼片段,我將一些視頻剪輯合併到一個視頻中,並使用'AVAssetExportSession'將其導出。但是,當我將'AVAssetExportSession'的'videoComposition'屬性設置爲'AVMutableVideoComposition'的實例時,出現錯誤。你知道如何在導出電影時使用你的代碼嗎?我在這裏提出了一個問題,如果你有時間,你可以看看嗎? http://stackoverflow.com/questions/16385017/error-when-using-avassetexportsession-with-video-composition-set – simonbs 2013-05-06 17:09:59

+0

@simonbs是否能夠得到它的工作? – 2015-06-15 18:46:13

11

如果全部你想保存你的視頻方向,你可能想分配AVMutableCompositionTrack preferredTransition價值從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; 
+0

這是最方便的方法。謝謝! – AlexeyVMP 2014-06-02 07:07:30

+2

如果構圖包含具有不同方向的曲目,這似乎不會奏效...... – 2014-11-03 17:29:40

+0

因爲它只考慮了lastObject。這是問題的簡化,而不是所有情況下的解決方案。 – Marcin 2014-11-03 20:04:37