Conversión de video MOV a Mp4 iPhone Programáticamente

Estoy desarrollando un server de medios para Play Station 3 en iPhone.

Llegué a saber que PS3 no es compatible con el file .MOV, así que tengo que convertirlo en Mp4 o algo más transcodificar qué PS3 admite.

Esto es lo que he hecho, pero se bloquea si configuro un tipo de file diferente al de sus files fuente.

AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil]; NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset]; if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) { AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetLowQuality]; exportSession.outputURL = [NSURL fileURLWithPath:videoPath]; exportSession.outputFileType = AVFileTypeMPEG4; CMTime start = CMTimeMakeWithSeconds(1.0, 600); CMTime duration = CMTimeMakeWithSeconds(3.0, 600); CMTimeRange range = CMTimeRangeMake(start, duration); exportSession.timeRange = range; [exportSession exportAsynchronouslyWithCompletionHandler:^{ switch ([exportSession status]) { case AVAssetExportSessionStatusFailed: NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]); break; case AVAssetExportSessionStatusCancelled: NSLog(@"Export canceled"); break; default: break; } [exportSession release]; }]; } 

Si establezco AVFileTypeMPEG4 aquí, se bloquea y dice "Tipo de file no válido". Así que tengo que configurarlo en AVFileTypeQuickTimeMovie y da el file MOV.

¿Es posible en iOS convertir video desde MOV a Mp4 a través de AVAssetExportSession … O sin ninguna librería Thirdparty?

presetName usa "AVAssetExportPresetPassthrough" en lugar de "AVAssetExportPresetLowQuality"

  AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough]; 

MOV es muy similar a MP4, puede que simplemente pueda cambiar la extensión y hacer que funcione, Windows Phone no puede reproducir .MOVS pero puede reproducir mp4, todo lo que hice para lograrlo es cambiar la extensión de .mov a .mp4 y funciona bien, y esto se debe a los videos grabados en el iPhone … y si es posible, intente exportar con AVAssetExporter e intente que hay un tipo de file allí para MP4 y M4A, como puede ver en las UTIs de formatting de file aquí

Espero eso ayude

Necesita AVMutableComposition para hacer esto. Porque Asset no se puede transcodificar a MP4 directamente con iOS 5.0.

 - (BOOL)encodeVideo:(NSURL *)videoURL { AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil]; // Create the composition and tracks AVMutableComposition *composition = [AVMutableComposition composition]; AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo prefernetworkingTrackID:kCMPersistentTrackID_Invalid]; AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio prefernetworkingTrackID:kCMPersistentTrackID_Invalid]; NSArray *assetVideoTracks = [asset tracksWithMediaType:AVMediaTypeVideo]; if (assetVideoTracks.count <= 0) { NSLog(@"Error reading the transformed video track"); return NO; } // Insert the tracks in the composition's tracks AVAssetTrack *assetVideoTrack = [assetVideoTracks firstObject]; [videoTrack insertTimeRange:assetVideoTrack.timeRange ofTrack:assetVideoTrack atTime:CMTimeMake(0, 1) error:nil]; [videoTrack setPrefernetworkingTransform:assetVideoTrack.prefernetworkingTransform]; AVAssetTrack *assetAudioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; [audioTrack insertTimeRange:assetAudioTrack.timeRange ofTrack:assetAudioTrack atTime:CMTimeMake(0, 1) error:nil]; // Export to mp4 NSString *mp4Quality = [MGPublic isIOSAbove:@"6.0"] ? AVAssetExportPresetMediumQuality : AVAssetExportPresetPassthrough; NSString *exportPath = [NSString stringWithFormat:@"%@/%@.mp4", [NSHomeDirectory() stringByAppendingString:@"/tmp"], [BSCommon uuidString]]; NSURL *exportUrl = [NSURL fileURLWithPath:exportPath]; AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:mp4Quality]; exportSession.outputURL = exportUrl; CMTime start = CMTimeMakeWithSeconds(0.0, 0); CMTimeRange range = CMTimeRangeMake(start, [asset duration]); exportSession.timeRange = range; exportSession.outputFileType = AVFileTypeMPEG4; [exportSession exportAsynchronouslyWithCompletionHandler:^{ switch ([exportSession status]) { case AVAssetExportSessionStatusCompleted: NSLog(@"MP4 Successful!"); break; case AVAssetExportSessionStatusFailed: NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]); break; case AVAssetExportSessionStatusCancelled: NSLog(@"Export canceled"); break; default: break; } }]; return YES; } 

Use el siguiente código

  NSURL * mediaURL = [info objectForKey:UIImagePickerControllerMediaURL]; AVAsset *video = [AVAsset assetWithURL:mediaURL]; AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality]; exportSession.shouldOptimizeForNetworkUse = YES; exportSession.outputFileType = AVFileTypeMPEG4; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; basePath = [basePath stringByAppendingPathComponent:@"videos"]; if (![[NSFileManager defaultManager] fileExistsAtPath:basePath]) [[NSFileManager defaultManager] createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:nil error:nil]; compressedVideoUrl=nil; compressedVideoUrl = [NSURL fileURLWithPath:basePath]; long CurrentTime = [[NSDate date] timeIntervalSince1970]; NSString *strImageName = [NSString stringWithFormat:@"%ld",CurrentTime]; compressedVideoUrl=[compressedVideoUrl URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4",strImageName]]; exportSession.outputURL = compressedVideoUrl; [exportSession exportAsynchronouslyWithCompletionHandler:^{ NSLog(@"done processing video!"); NSLog(@"%@",compressedVideoUrl); if(!dataMovie) dataMovie = [[NSMutableData alloc] init]; dataMovie = [NSData dataWithContentsOfURL:compressedVideoUrl]; }]; 

Puede convertir video en mp4 por AVAssets.

 AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil]; NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset]; AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetLowQuality]; NSString* documentsDirectory=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; exportSession.outputURL = url; //set the output file format if you want to make it in other file format (ex .3gp) exportSession.outputFileType = AVFileTypeMPEG4; exportSession.shouldOptimizeForNetworkUse = YES; [exportSession exportAsynchronouslyWithCompletionHandler:^{ switch ([exportSession status]) { case AVAssetExportSessionStatusFailed: NSLog(@"Export session failed"); break; case AVAssetExportSessionStatusCancelled: NSLog(@"Export canceled"); break; case AVAssetExportSessionStatusCompleted: { //Video conversion finished NSLog(@"Successful!"); } break; default: break; } }]; 

Para convertir fácilmente video a mp4, use este enlace .

También puede encontrar un proyecto de muestra para convertir video a mp4.

Solo quería decir que la URL no puede ser como

 [NSURL URLWithString: [@"~/Documents/movie.mov" stringByExpandingTildeInPath]] 

Debe ser como

 [NSURL fileURLWithPath: [@"~/Documents/movie.mov" stringByExpandingTildeInPath]] 

Me llevó un time resolver eso 🙂

Aquí está el código

  func encodeVideo(videoURL: NSURL) { let avAsset = AVURLAsset(URL: videoURL, options: nil) var startDate = NSDate() //Create Export session exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough) // exportSession = AVAssetExportSession(asset: composition, presetName: mp4Quality) //Creating temp path to save the converted video let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] let myDocumentPath = NSURL(fileURLWithPath: documentsDirectory).URLByAppendingPathComponent("temp.mp4").absoluteString let url = NSURL(fileURLWithPath: myDocumentPath) let documentsDirectory2 = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL let filePath = documentsDirectory2.URLByAppendingPathComponent("rendenetworking-Video.mp4") deleteFile(filePath) //Check if the file already exists then remove the previous file if NSFileManager.defaultManager().fileExistsAtPath(myDocumentPath) { do { try NSFileManager.defaultManager().removeItemAtPath(myDocumentPath) } catch let error { print(error) } } url exportSession!.outputURL = filePath exportSession!.outputFileType = AVFileTypeMPEG4 exportSession!.shouldOptimizeForNetworkUse = true var start = CMTimeMakeWithSeconds(0.0, 0) var range = CMTimeRangeMake(start, avAsset.duration) exportSession.timeRange = range exportSession!.exportAsynchronouslyWithCompletionHandler({() -> Void in switch self.exportSession!.status { case .Failed: print("%@",self.exportSession?.error) case .Cancelled: print("Export canceled") case .Completed: //Video conversion finished var endDate = NSDate() var time = endDate.timeIntervalSinceDate(startDate) print(time) print("Successful!") print(self.exportSession.outputURL) default: break } }) } func deleteFile(filePath:NSURL) { guard NSFileManager.defaultManager().fileExistsAtPath(filePath.path!) else { return } do { try NSFileManager.defaultManager().removeItemAtPath(filePath.path!) }catch{ fatalError("Unable to delete file: \(error) : \(__FUNCTION__).") } }