录制,保存和/或转换MP4格式的video?

我有以下问题 – 我正在尝试创build一个loggingvideo的应用程序,然后将其保存到相机胶卷,之后我将该video上传到networking。 问题是唯一支持的格式是“mp4”,但我的video是“mov”。

所以我的问题是如何从“mp4”格式保存摄像机的video,或保存在“mov”,然后将其转换为“mp4”。

这是我的代码:

  • 这是我如何打开相机:

    picker = [[UIImagePickerController alloc] init]; picker.sourceType = UIImagePickerControllerSourceTypeCamera; picker.delegate = self; picker.showsCameraControls = YES; picker.allowsEditing = YES; picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil]; [self presentViewController:picker animated:YES completion:nil]; 
  • 这是我如何保存video:

     NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType]; if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) { NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path]; videoURL = info[UIImagePickerControllerMediaURL]; if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath)) { UISaveVideoAtPathToSavedPhotosAlbum(moviePath, self, nil, nil); } } [nextScreenButton setTitle:@"ПРОДЪЛЖИ" forState:UIControlStateNormal]; [self dismissViewControllerAnimated:YES completion:nil]; 

提前致谢!

你正在做正确的事情..现在你需要将这个mov文件转换为mp4如下。

 NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType]; NSString *videoPath1 = @""; if (CFStringCompare ((__bridge_retained CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) { if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath)) { NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path]; videoPath1 =[NSString stringWithFormat:@"%@/xyz.mov",docDir]; NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL]; NSData *videoData = [NSData dataWithContentsOfURL:videoURL]; [videoData writeToFile:videoPath1 atomically:NO]; // UISaveVideoAtPathToSavedPhotosAlbum(moviePath, self, nil, nil); } } AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:videoPath1] options:nil]; NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset]; if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) { AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); videoPath = [NSString stringWithFormat:@"%@/xyz.mp4", [paths objectAtIndex:0]]; exportSession.outputURL = [NSURL fileURLWithPath:videoPath]; NSLog(@"videopath of your mp4 file = %@",videoPath); // PATH OF YOUR .mp4 FILE exportSession.outputFileType = AVFileTypeMPEG4; // CMTime start = CMTimeMakeWithSeconds(1.0, 600); // CMTime duration = CMTimeMakeWithSeconds(3.0, 600); // CMTimeRange range = CMTimeRangeMake(start, duration); // exportSession.timeRange = range; // UNCOMMENT ABOVE LINES FOR CROP VIDEO [exportSession exportAsynchronouslyWithCompletionHandler:^{ switch ([exportSession status]) { case AVAssetExportSessionStatusFailed: NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]); break; case AVAssetExportSessionStatusCancelled: NSLog(@"Export canceled"); break; default: break; } UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self, nil, nil); [exportSession release]; }]; } [nextScreenButton setTitle:@"ПРОДЪЛЖИ" forState:UIControlStateNormal]; [self dismissViewControllerAnimated:YES completion:nil]; 

这里是代码将movvideo转换成mp4为swift

 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("rendered-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__).") } } 

Swift 3

 func encodeVideo(_ videoURL: URL) { let avAsset = AVURLAsset(url: videoURL, options: nil) let startDate = Foundation.Date() //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 = URL(fileURLWithPath: documentsDirectory).appendingPathComponent("temp.mp4").absoluteString let url = URL(fileURLWithPath: myDocumentPath) let documentsDirectory2 = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL let filePath = documentsDirectory2.appendingPathComponent("rendered-Video.mp4") deleteFile(filePath) //Check if the file already exists then remove the previous file if FileManager.default.fileExists(atPath: myDocumentPath) { do { try FileManager.default.removeItem(atPath: myDocumentPath) } catch let error { print(error) } } exportSession!.outputURL = filePath exportSession!.outputFileType = AVFileTypeMPEG4 exportSession!.shouldOptimizeForNetworkUse = true let start = CMTimeMakeWithSeconds(0.0, 0) let range = CMTimeRangeMake(start, avAsset.duration) exportSession.timeRange = range exportSession!.exportAsynchronously(completionHandler: {() -> Void in switch self.exportSession!.status { case .failed: print("%@",self.exportSession?.error) case .cancelled: print("Export canceled") case .completed: //Video conversion finished let endDate = Foundation.Date() let time = endDate.timeIntervalSince(startDate) print(time) print("Successful!") print(self.exportSession.outputURL) self.mediaPath = self.exportSession.outputURL?.path as NSString! //self.mediaPath = String(self.exportSession.outputURL!) // self.mediaPath = self.mediaPath.substringFromIndex(7) default: break } }) } func deleteFile(_ filePath:URL) { guard FileManager.default.fileExists(atPath: filePath.path) else { return } do { try FileManager.default.removeItem(atPath: filePath.path) }catch{ fatalError("Unable to delete file: \(error) : \(#function).") } } 

在这里你可以指定压缩video的videotypes,质量和输出url。

看下面的方法:

 - (void) saveVideoToLocal:(NSURL *)videoURL { @try { NSArray *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docPath = [documentsDirectory objectAtIndex:0]; NSString *videoName = [NSString stringWithFormat:@"sampleVideo.mp4"]; NSString *videoPath = [docPath stringByAppendingPathComponent:videoName]; NSURL *outputURL = [NSURL fileURLWithPath:videoPath]; NSLog(@"Loading video"); [self convertVideoToLowQuailtyWithInputURL:videoURL outputURL:outputURL handler:^(AVAssetExportSession *exportSession) { if (exportSession.status == AVAssetExportSessionStatusCompleted) { NSLog(@"Compression is done"); } }]; } @catch (NSException *exception) { NSLog(@"Exception :%@",exception.description); } } //--------------------------------------------------------------- - (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL handler:(void (^)(AVAssetExportSession*))handler { [[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil]; AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil]; AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetPassthrough]; exportSession.outputURL = outputURL; exportSession.outputFileType = AVFileTypeMPEG4; [exportSession exportAsynchronouslyWithCompletionHandler:^(void) { handler(exportSession); }]; } 

可以,您可以使用AVAssetExportSession压缩video。 在这里,我将压缩video保存到应用程序的document directory 。 你可以在这个代码中查看这个细节的工作。

如果你仍然有问题,那么请参考这个和这个 。