Tôi đang cố xoay video trước khi tải lên trên thiết bị iOS của mình vì các nền tảng khác (chẳng hạn như android) không giải thích đúng thông tin xoay trong video được ghi iOS và kết quả là phát chúng xoay không đúng cách.AVAssetExportSession bỏ qua videoVideo xoay vòng và siêu dữ liệu loại trừ
Tôi đã nhìn vào đống bài viết sau đây nhưng chưa có thành công áp dụng bất kỳ trong số họ để trường hợp của tôi:
tôi đối phó các mẫu dự án Apple AVSimpleEditor, nhưng tiếc là tất cả những gì đã từng xảy ra là, khi tạo ra một AVAssetExportSession và gọi exportAsynchronouslyWithCompletionHandler, không luân chuyển được thực hiện, và những gì tồi tệ hơn, siêu dữ liệu luân chuyển được lột ra khỏi kết quả tập tin.
Đây là mã chạy tệp xuất:
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:[_mutableComposition copy] presetName:AVAssetExportPresetPassthrough];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileType3GPP;
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.videoComposition = _mutableVideoComposition;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
NSLog(@"Status is %d %@", exportSession.status, exportSession.error);
handler(exportSession);
[exportSession release];
}];
Các giá trị _mutableComposition và _mutableVideoComposition được khởi tạo bằng phương pháp này ở đây:
- (void) getVideoComposition:(AVAsset*)asset
{
AVMutableComposition *mutableComposition = nil;
AVMutableVideoComposition *mutableVideoComposition = nil;
AVMutableVideoCompositionInstruction *instruction = nil;
AVMutableVideoCompositionLayerInstruction *layerInstruction = nil;
CGAffineTransform t1;
CGAffineTransform t2;
AVAssetTrack *assetVideoTrack = nil;
AVAssetTrack *assetAudioTrack = nil;
// Check if the asset contains video and audio tracks
if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) {
assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0];
}
if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) {
assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0];
}
CMTime insertionPoint = kCMTimeZero;
NSError *error = nil;
// Step 1
// Create a composition with the given asset and insert audio and video tracks into it from the asset
// Check whether a composition has already been created, i.e, some other tool has already been applied
// Create a new composition
mutableComposition = [AVMutableComposition composition];
// Insert the video and audio tracks from AVAsset
if (assetVideoTrack != nil) {
AVMutableCompositionTrack *compositionVideoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetVideoTrack atTime:insertionPoint error:&error];
}
if (assetAudioTrack != nil) {
AVMutableCompositionTrack *compositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetAudioTrack atTime:insertionPoint error:&error];
}
// Step 2
// Translate the composition to compensate the movement caused by rotation (since rotation would cause it to move out of frame)
t1 = CGAffineTransformMakeTranslation(assetVideoTrack.naturalSize.height, 0.0);
// Rotate transformation
t2 = CGAffineTransformRotate(t1, degreesToRadians(90.0));
// Step 3
// Set the appropriate render sizes and rotational transforms
// Create a new video composition
mutableVideoComposition = [AVMutableVideoComposition videoComposition];
mutableVideoComposition.renderSize = CGSizeMake(assetVideoTrack.naturalSize.height,assetVideoTrack.naturalSize.width);
mutableVideoComposition.frameDuration = CMTimeMake(1, 30);
// The rotate transform is set on a layer instruction
instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mutableComposition duration]);
layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:(mutableComposition.tracks)[0]];
[layerInstruction setTransform:t2 atTime:kCMTimeZero];
// Step 4
// Add the transform instructions to the video composition
instruction.layerInstructions = @[layerInstruction];
mutableVideoComposition.instructions = @[instruction];
TT_RELEASE_SAFELY(_mutableComposition);
_mutableComposition = [mutableComposition retain];
TT_RELEASE_SAFELY(_mutableVideoComposition);
_mutableVideoComposition = [mutableVideoComposition retain];
}
Tôi kéo phương pháp này từ AVSERotateCommand from here. Bất cứ ai có thể đề nghị tại sao phương pháp này sẽ không thành công xoay video của tôi bằng 90 độ cần thiết?
Tôi gặp vấn đề tương tự như bạn đã làm và câu trả lời được đề xuất bên dưới (thay đổi thành AVAssetExportPresetMediumQuality chẳng hạn) không giải quyết được sự cố. Tôi đã thử thêm setOpacity: 0 trên lớpHướng dẫn, nhưng có vẻ như các hướng dẫn bị bỏ qua khi xuất phim. –
tôi cũng có cùng một vấn đề, bạn có giải pháp nào không? – user3306145