Sto provando a convertire il video .mov in .mp4 e allo stesso tempo correggere l'orientamento. Il codice che uso qui di seguito grandi opere durante la registrazione di un video utilizzando UIImagePickerController
se il video è selezionato dal rullino fotografico ottengo questo errore e non vedo il motivo per cui:Errore di rotazione di AVAssetExportSession quando il video proviene dal rullino fotografico
esportazione non riuscita: un'operazione interrotta: Errore dominio = Codice AVFoundationErrorDomain = -11.841 "Operazione Stopped" UserInfo = {0x1815ca50 NSLocalizedDescription = Operazione Arrestato, NSLocalizedFailureReason = il video non poteva essere composto.}
ho provato prima il salvataggio del video in un altro file, ma non ha fatto differenza.
Ecco il codice che sto usando per convertire il video:
- (void)convertVideoToLowQuailtyAndFixRotationWithInputURL:(NSURL*)inputURL handler:(void (^)(NSURL *outURL))handler
{
if ([[inputURL pathExtension] isEqualToString:@"MOV"])
{
NSURL *outputURL = [inputURL URLByDeletingPathExtension];
outputURL = [outputURL URLByAppendingPathExtension:@"mp4"];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetTrack *sourceVideoTrack = [[avAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *sourceAudioTrack = [[avAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVMutableComposition* composition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration)
ofTrack:sourceVideoTrack
atTime:kCMTimeZero error:nil];
[compositionVideoTrack setPreferredTransform:sourceVideoTrack.preferredTransform];
AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration)
ofTrack:sourceAudioTrack
atTime:kCMTimeZero error:nil];
AVMutableVideoComposition *videoComposition = [self getVideoComposition:avAsset];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetMediumQuality])
{
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:composition presetName:AVAssetExportPresetMediumQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.videoComposition = videoComposition;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status])
{
case AVAssetExportSessionStatusFailed:
NSLog(@"Export failed: %@ : %@", [[exportSession error] localizedDescription], [exportSession error]);
handler(nil);
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"Export canceled");
handler(nil);
break;
default:
handler(outputURL);
break;
}
}];
}
} else {
handler(inputURL);
}
}
- (AVMutableVideoComposition *)getVideoComposition:(AVAsset *)asset
{
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableComposition *composition = [AVMutableComposition composition];
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
CGSize videoSize = videoTrack.naturalSize;
BOOL isPortrait_ = [self isVideoPortrait:asset];
if(isPortrait_) {
// NSLog(@"video is portrait ");
videoSize = CGSizeMake(videoSize.height, videoSize.width);
}
composition.naturalSize = videoSize;
videoComposition.renderSize = videoSize;
videoComposition.frameDuration = CMTimeMakeWithSeconds(1/videoTrack.nominalFrameRate, 600);
AVMutableCompositionTrack *compositionVideoTrack;
compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:videoTrack atTime:kCMTimeZero error:nil];
AVMutableVideoCompositionLayerInstruction *layerInst;
layerInst = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
[layerInst setTransform:videoTrack.preferredTransform atTime:kCMTimeZero];
AVMutableVideoCompositionInstruction *inst = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
inst.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
inst.layerInstructions = [NSArray arrayWithObject:layerInst];
videoComposition.instructions = [NSArray arrayWithObject:inst];
return videoComposition;
}
Grazie per la vostra risposta molto dettagliata. Non riesco ancora a far funzionare :( 'componable',' exportable' e 'hasProtectedContent' sono4 tutto come dici tu.Non ci sono errori restituiti dal tuo primo suggerimento.Ho provato a cambiare la traccia audio per usare 44.100. Se commento "exportSession.videoComposition = videoComposition;" funziona bene, tuttavia il video non viene ruotato, quindi il problema deve essere lì da qualche parte. Grazie – Darren
Mi accorgo che crei un 'AVMutableComposition' in' - (AVMutableVideoComposition *) getVideoComposition', e crea 'AVMutableCompositionTrack's da quello.Tuttavia, in' - (void) convertVideoToLowQuailtyAndFixRotationWithInputURL: handler: ' , hai un _different_' AVMutableComposition' che stai passando a 'AVExportSession'. Prova a passare questa composizione a getVideoComposition per creare AVMutableCompositionTracks da questo, quindi ce n'è uno solo. – jlw
I just ho provato a spostare "AVMutableVideoComposition' con" AVMutableVideoCompositionLayerInstruction' verso l'alto nel metodo di conversione principale in modo che abbia solo 1 "AVMutableComposition' ma abbia sempre gli stessi risultati. Quando si seleziona un video dal rullino fotografico, lo comprime prima di passarlo sopra, non è sicuro se questo è ciò che fa la differenza. – Darren