ios - quemar - grabar mp4 a dvd para verlos en un dvd casero
¿Grabar, guardar y/o convertir video en formato mp4? (3)
Tengo el siguiente problema: estoy tratando de crear una aplicación que graba video, luego lo guardo en el rollo de la cámara y después de eso estoy subiendo ese video a la web. El problema es que el único formato compatible es "mp4", pero mis videos son "mov".
Así que mi pregunta es cómo guardar el video de la cámara en formato "mp4", o guardarlo en "mov" y luego convertirlo a "mp4".
Aquí está mi código:
Así es como abro la cámara:
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];
Así es como guardo el 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];
¡Gracias por adelantado!
Aquí está el código para convertir video mov en mp4 para 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).")
}
}
Aquí puede especificar el tipo de video, la calidad y la url de salida para comprimir video.
Vea los métodos a continuación:
- (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);
}];
}
Sí, puede comprimir video usando AVAssetExportSession
. Aquí, guardé el video comprimido en el document directory
de document directory
de la aplicación. Puedes verificar el detalle de esto en este código .
Está haciendo lo correcto. Ahora necesita convertir este archivo mov a mp4 como se muestra a continuación.
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];