【问题标题】:Record, save and/or convert video in mp4 format?以 mp4 格式录制、保存和/或转换视频?
【发布时间】:2013-12-15 11:13:55
【问题描述】:

我有以下问题 - 我正在尝试创建一个录制视频的应用程序,然后将其保存到相机胶卷,然后我将该视频上传到网络。问题是唯一支持的格式是“mp4”,但我的视频是“mov”。

所以我的问题是如何将相机中的视频保存为“mp4”格式,或者将其保存为“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];
    
  • 这就是我保存视频的方式:

    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];
    

提前致谢!

【问题讨论】:

    标签: ios iphone xcode video mp4


    【解决方案1】:

    在 Swift 中将视频转换为 mp4 的 Swift 5 代码

    首先你需要导入这个

    import AVFoundation
    

    然后您可以编写此代码并将 URL 传递给它。

    func videoConvert(videoURL: URL)  {
        let avAsset = AVURLAsset(url: videoURL as URL, options: nil)
        let startDate = NSDate()
        //Create Export session
    
        let 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).appendingPathComponent("temp.mp4")?.absoluteString
        let url = NSURL(fileURLWithPath: myDocumentPath!)
    
        let documentsDirectory2 = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as NSURL
        let filePath = documentsDirectory2.appendingPathComponent("VideoConvert.mp4")
        deleteFile(filePath: 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)
            }
        }
        //URL
        print(filePath!.absoluteString)
        exportSession!.outputURL = filePath
        exportSession!.outputFileType = AVFileType.mp4
        exportSession!.shouldOptimizeForNetworkUse = true
        let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)
        let range = CMTimeRangeMake(start: start, duration: avAsset.duration)
        exportSession!.timeRange = range
        exportSession!.exportAsynchronously(completionHandler: {() -> Void in
            switch exportSession!.status {
                case .failed:
                    print("%@",exportSession!.error ?? "Failed to get error")
                case .cancelled:
                    print("Export canceled")
                case .completed:
                    //Video conversion finished
                    let endDate = NSDate()
                    let time = endDate.timeIntervalSince(startDate as Date)
                    print(time)
                    print("Successful!")
                    print(exportSession!.outputURL)
                default:
                    break
            }
        })
    }
    

    为了调用你可以使用的函数

    videoConvert(videoURL: fileUrl!)
    

    self.videoConvert(videoURL: fileUrl!)
    

    然后您将转换视频并存储到名为 VideoConvert.mp4

    document 目录中

    感谢@Jigar Thakkar 的回答。

    【讨论】:

      【解决方案2】:

      这里是将mov视频快速转换为mp4的代码

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

      斯威夫特 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).")
          }
      }
      

      【讨论】:

      • 给你声誉不足以回答这个问题。惊人的。谢谢。
      【解决方案3】:

      您可以在此处指定视频类型、质量和压缩视频的输出网址。

      见以下方法:

      - (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 压缩视频。在这里,我将压缩视频保存到应用程序的document directory。您可以在this code 中查看详细工作情况。

      如果您仍有问题,请参考thisthis

      【讨论】:

        【解决方案4】:

        你做对了。现在你需要将这个 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];
        

        【讨论】:

        • 谢谢,伙计,这行得通。还有一件事——.mp4视频文件只有3秒,如何让它像.mov文件一样长?
        • 请查看我编辑的答案。我评论了范围部分。它会工作
        • 谢谢,最后一件事 - 它在我的相册中保存了两个视频,如何让它只保存 mp4 视频文件?
        • 两个视频都是mov还是1是mov而1是mp4?
        • 完全看不懂这个。您在 if 语句中定义了 videoPath1 并在外部使用它。该代码无法编译。您能否更新一个至少可以编译的答案。
        猜你喜欢
        • 2011-06-28
        • 1970-01-01
        • 1970-01-01
        • 2013-03-06
        • 2012-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-24
        相关资源
        最近更新 更多