iOS video recording (or optional) compression and upload function (finishing)

  • 2021-12-04 20:01:05
  • OfStack

The latest function involves recording, compressing and uploading videos. According to the experience of many great gods on the Internet, I finally got through, but I also found some problems, so I shared my experience.

First of all, it must be called the camera or photo album of the system under 1

The code is basic:


// Select local video  
- (void)choosevideo 
{ 
 UIImagePickerController *ipc = [[UIImagePickerController alloc] init]; 
 ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//sourcetype Have 3 The species are camera , photoLibrary And photoAlbum 
 NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera Supported Media What are the formats , There are two are @"public.image",@"public.movie" 
 ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];// Set the media type to public.movie 
 [self presentViewController:ipc animated:YES completion:nil]; 
 ipc.delegate = self;// Set Delegation  
} 
// Record a video  
- (void)startvideo 
{ 
 UIImagePickerController *ipc = [[UIImagePickerController alloc] init]; 
 ipc.sourceType = UIImagePickerControllerSourceTypeCamera;//sourcetype Have 3 The species are camera , photoLibrary And photoAlbum 
 NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera Supported Media What are the formats , There are two are @"public.image",@"public.movie" 
 ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];// Set the media type to public.movie 
 [self presentViewController:ipc animated:YES completion:nil]; 
 ipc.videoMaximumDuration = 30.0f;//30 Seconds  
 ipc.delegate = self;// Set Delegation  
} 

The video format recorded by iOS is mov, which is not well supported on Android and Pc, so it is necessary to convert it to MP4 format, and compress it for 1 time. After all, all the videos we upload are small videos, so we don't need to be particularly clear

In order to feedback clearly, first put two small codes to get the length and size of the video, which is also found on the Internet, and slightly changed 1.


- (CGFloat) getFileSize:(NSString *)path 
{ 
 NSLog(@"%@",path); 
 NSFileManager *fileManager = [NSFileManager defaultManager]; 
 float filesize = -1.0; 
 if ([fileManager fileExistsAtPath:path]) { 
  NSDictionary *fileDic = [fileManager attributesOfItemAtPath:path error:nil];// Get the properties of the file  
  unsigned long long size = [[fileDic objectForKey:NSFileSize] longLongValue]; 
  filesize = 1.0*size/1024; 
 }else{ 
  NSLog(@" File not found "); 
 } 
 return filesize; 
}// This method can get the size of the file and return the unit is KB .  
- (CGFloat) getVideoLength:(NSURL *)URL 
{ 
 AVURLAsset *avUrl = [AVURLAsset assetWithURL:URL]; 
 CMTime time = [avUrl duration]; 
 int second = ceil(time.value/time.timescale); 
 return second; 
}// This method can get the duration of the video file. 

Receive and compress


// Complete video recording, and display the size and duration after compression  
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 
{ 
 NSURL *sourceURL = [info objectForKey:UIImagePickerControllerMediaURL]; 
 NSLog(@"%@",[NSString stringWithFormat:@"%f s", [self getVideoLength:sourceURL]]); 
 NSLog(@"%@", [NSString stringWithFormat:@"%.2f kb", [self getFileSize:[sourceURL path]]]); 
 NSURL *newVideoUrl ; //1 Like .mp4 
 NSDateFormatter *formater = [[NSDateFormatter alloc] init];// Use time to give the full name of the file to avoid duplication. In fact, when testing, you can judge whether the file exists. If it exists, delete and regenerate the file.  
 [formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss"]; 
 newVideoUrl = [NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingFormat:@"/Documents/output-%@.mp4", [formater stringFromDate:[NSDate date]]]] ;// This is stored in app In your own sandbox path, you can choose whether to delete it after uploading. I suggest deleting it so as not to take up space.  
 [picker dismissViewControllerAnimated:YES completion:nil]; 
 [self convertVideoQuailtyWithInputURL:sourceURL outputURL:newVideoUrl completeHandler:nil]; 
} 
- (void) convertVideoQuailtyWithInputURL:(NSURL*)inputURL 
        outputURL:(NSURL*)outputURL 
       completeHandler:(void (^)(AVAssetExportSession*))handler 
{ 
 AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:inputURL options:nil]; 
  AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality]; 
  // NSLog(resultPath); 
  exportSession.outputURL = outputURL; 
  exportSession.outputFileType = AVFileTypeMPEG4; 
  exportSession.shouldOptimizeForNetworkUse= YES; 
  [exportSession exportAsynchronouslyWithCompletionHandler:^(void) 
   { 
    switch (exportSession.status) { 
     case AVAssetExportSessionStatusCancelled: 
      NSLog(@"AVAssetExportSessionStatusCancelled"); 
      break; 
     case AVAssetExportSessionStatusUnknown: 
      NSLog(@"AVAssetExportSessionStatusUnknown"); 
      break; 
     case AVAssetExportSessionStatusWaiting: 
      NSLog(@"AVAssetExportSessionStatusWaiting"); 
      break; 
     case AVAssetExportSessionStatusExporting: 
      NSLog(@"AVAssetExportSessionStatusExporting"); 
      break; 
     case AVAssetExportSessionStatusCompleted: 
      NSLog(@"AVAssetExportSessionStatusCompleted"); 
      NSLog(@"%@",[NSString stringWithFormat:@"%f s", [self getVideoLength:outputURL]]); 
      NSLog(@"%@", [NSString stringWithFormat:@"%.2f kb", [self getFileSize:[outputURL path]]]); 
      //UISaveVideoAtPathToSavedPhotosAlbum([outputURL path], self, nil, NULL);// This is saved to the mobile phone photo album  
      [self alertUploadVideo:outputURL]; 
      break; 
     case AVAssetExportSessionStatusFailed: 
      NSLog(@"AVAssetExportSessionStatusFailed"); 
      break; 
    } 
   }]; 
} 

I used a reminder here, because my server is weak and can't transfer too large files


-(void)alertUploadVideo:(NSURL*)URL{ 
 CGFloat size = [self getFileSize:[URL path]]; 
 NSString *message; 
 NSString *sizeString; 
 CGFloat sizemb= size/1024; 
 if(size<=1024){ 
  sizeString = [NSString stringWithFormat:@"%.2fKB",size]; 
 }else{ 
  sizeString = [NSString stringWithFormat:@"%.2fMB",sizemb]; 
 } 
 if(sizemb<2){ 
  [self uploadVideo:URL]; 
 } 
 else if(sizemb<=5){ 
  message = [NSString stringWithFormat:@" Video %@ , greater than 2MB It will be a little slow. Are you sure you want to upload it? ", sizeString]; 
  UIAlertController * alertController = [UIAlertController alertControllerWithTitle: nil 
                     message: message 
                   preferredStyle:UIAlertControllerStyleAlert]; 
  [alertController addAction:[UIAlertAction actionWithTitle:@" Cancel " style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
   [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshwebpages" object:nil userInfo:nil]; 
   [[NSFileManager defaultManager] removeItemAtPath:[URL path] error:nil];// Delete after cancellation, so as not to occupy the hard disk space of mobile phone (sandbox)  
  }]]; 
  [alertController addAction:[UIAlertAction actionWithTitle:@" Determine " style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
   [self uploadVideo:URL]; 
  }]]; 
  [self presentViewController:alertController animated:YES completion:nil]; 
 }else if(sizemb>5){ 
  message = [NSString stringWithFormat:@" Video %@ , more than 5MB Can't upload, sorry. ", sizeString]; 
  UIAlertController * alertController = [UIAlertController alertControllerWithTitle: nil 
                     message: message 
                   preferredStyle:UIAlertControllerStyleAlert]; 
  [alertController addAction:[UIAlertAction actionWithTitle:@" Determine " style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { 
   [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshwebpages" object:nil userInfo:nil]; 
   [[NSFileManager defaultManager] removeItemAtPath:[URL path] error:nil];// Delete after cancellation, so as not to occupy the hard disk space of mobile phone  
  }]]; 
  [self presentViewController:alertController animated:YES completion:nil]; 
 } 
} 

Upload the last code, this is according to the server, but also the use of MKNetworking, it is said that has been outdated, put up everyone to refer to 1, AFNet is similar, that is, NSData.


-(void)uploadVideo:(NSURL*)URL{ 
 //[MyTools showTipsWithNoDisappear:nil message:@" Uploading ..."]; 
 NSData *data = [NSData dataWithContentsOfURL:URL]; 
 MKNetworkEngine *engine = [[MKNetworkEngine alloc] initWithHostName:@"www.ylhuakai.com" customHeaderFields:nil]; 
 NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; 
 NSString *updateURL; 
 updateURL = @"/alflower/Data/sendupdate"; 
 [dic setValue:[NSString stringWithFormat:@"%@",User_id] forKey:@"openid"]; 
 [dic setValue:[NSString stringWithFormat:@"%@",[self.web objectForKey:@"web_id"]] forKey:@"web_id"]; 
 [dic setValue:[NSString stringWithFormat:@"%i",insertnumber] forKey:@"number"]; 
 [dic setValue:[NSString stringWithFormat:@"%i",insertType] forKey:@"type"]; 
 MKNetworkOperation *op = [engine operationWithPath:updateURL params:dic httpMethod:@"POST"]; 
 [op addData:data forKey:@"video" mimeType:@"video/mpeg" fileName:@"aa.mp4"]; 
 [op addCompletionHandler:^(MKNetworkOperation *operation) { 
  NSLog(@"[operation responseData]-->>%@", [operation responseString]); 
  NSData *data = [operation responseData]; 
  NSDictionary *resweiboDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; 
  NSString *status = [[resweiboDict objectForKey:@"status"]stringValue]; 
  NSLog(@"addfriendlist status is %@", status); 
  NSString *info = [resweiboDict objectForKey:@"info"]; 
  NSLog(@"addfriendlist info is %@", info); 
  // [MyTools showTipsWithView:nil message:info]; 
  // [SVProgressHUD showErrorWithStatus:info]; 
  if ([status isEqualToString:@"1"]) 
  { 
   [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshwebpages" object:nil userInfo:nil]; 
   [[NSFileManager defaultManager] removeItemAtPath:[URL path] error:nil];// Delete after uploading, so as not to occupy the hard disk space of mobile phone ; 
  }else 
  { 
   //[SVProgressHUD showErrorWithStatus:dic[@"info"]]; 
  } 
  // [[NSNotificationCenter defaultCenter] postNotificationName:@"StoryData" object:nil userInfo:nil]; 
 }errorHandler:^(MKNetworkOperation *errorOp, NSError* err) { 
  NSLog(@"MKNetwork request error : %@", [err localizedDescription]); 
 }]; 
 [engine enqueueOperation:op]; 
} 

Related articles: