iOS视频录制(或选择)压缩及上传功能(整理)

最新做的一个功能涉及到了视频的录制、压缩及上传。根据网上诸多大神的经验,终于算是调通了,但也发现了一些问题,所以把我的经验分享一下。

首先,肯定是调用一下系统的相机或相册

代码很基本:

//选择本地视频
- (void)choosevideo
{
 UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
 ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//sourcetype有三种分别是camera,photoLibrary和photoAlbum
 NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera所支持的Media格式都有哪些,共有两个分别是@"public.image",@"public.movie"
 ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];//设置媒体类型为public.movie
 [self presentViewController:ipc animated:YES completion:nil];
 ipc.delegate = self;//设置委托
}
//录制视频
- (void)startvideo
{
 UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
 ipc.sourceType = UIImagePickerControllerSourceTypeCamera;//sourcetype有三种分别是camera,photoLibrary和photoAlbum
 NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera所支持的Media格式都有哪些,共有两个分别是@"public.image",@"public.movie"
 ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];//设置媒体类型为public.movie
 [self presentViewController:ipc animated:YES completion:nil];
 ipc.videoMaximumDuration = 30.0f;//30秒
 ipc.delegate = self;//设置委托
} 

iOS录制的视频格式是mov的,在Android和Pc上都不太好支持,所以要转换为MP4格式的,而且压缩一下,毕竟我们上传的都是小视频,不用特别清楚

为了反馈的清楚,先放两个小代码来获取视频的时长和大小,也是在网上找的,稍微改了一下。

- (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];//获取文件的属性
  unsigned long long size = [[fileDic objectForKey:NSFileSize] longLongValue];
  filesize = 1.0*size/1024;
 }else{
  NSLog(@"找不到文件");
 }
 return filesize;
}//此方法可以获取文件的大小,返回的是单位是KB。
- (CGFloat) getVideoLength:(NSURL *)URL
{
 AVURLAsset *avUrl = [AVURLAsset assetWithURL:URL];
 CMTime time = [avUrl duration];
 int second = ceil(time.value/time.timescale);
 return second;
}//此方法可以获取视频文件的时长。

 接收并压缩

//完成视频录制,并压缩后显示大小、时长
- (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 ; //一般.mp4
 NSDateFormatter *formater = [[NSDateFormatter alloc] init];//用时间给文件全名,以免重复,在测试的时候其实可以判断文件是否存在若存在,则删除,重新生成文件即可
 [formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
 newVideoUrl = [NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingFormat:@"/Documents/output-%@.mp4", [formater stringFromDate:[NSDate date]]]] ;//这个是保存在app自己的沙盒路径里,后面可以选择是否在上传后删除掉。我建议删除掉,免得占空间。
 [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);//这个是保存到手机相册
      [self alertUploadVideo:outputURL];
      break;
     case AVAssetExportSessionStatusFailed:
      NSLog(@"AVAssetExportSessionStatusFailed");
      break;
    }
   }];
} 

我这里用了一个提醒,因为我的服务器比较弱,不能传太大的文件

-(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:@"视频%@,大于2MB会有点慢,确定上传吗?", sizeString];
  UIAlertController * alertController = [UIAlertController alertControllerWithTitle: nil
                     message: message
                   preferredStyle:UIAlertControllerStyleAlert];
  [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
   [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshwebpages" object:nil userInfo:nil];
   [[NSFileManager defaultManager] removeItemAtPath:[URL path] error:nil];//取消之后就删除,以免占用手机硬盘空间(沙盒)
  }]];
  [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
   [self uploadVideo:URL];
  }]];
  [self presentViewController:alertController animated:YES completion:nil];
 }else if(sizemb>5){
  message = [NSString stringWithFormat:@"视频%@,超过5MB,不能上传,抱歉。", sizeString];
  UIAlertController * alertController = [UIAlertController alertControllerWithTitle: nil
                     message: message
                   preferredStyle:UIAlertControllerStyleAlert];
  [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
   [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshwebpages" object:nil userInfo:nil];
   [[NSFileManager defaultManager] removeItemAtPath:[URL path] error:nil];//取消之后就删除,以免占用手机硬盘空间
  }]];
  [self presentViewController:alertController animated:YES completion:nil];
 }
} 

最后上上传的代码,这个是根据服务器来的,而且还是用的MKNetworking,据说已经过时了,放上来大家参考一下吧,AFNet也差不多,就是把NSData传上去。

-(void)uploadVideo:(NSURL*)URL{
 //[MyTools showTipsWithNoDisappear:nil message:@"正在上传..."];
 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];//上传之后就删除,以免占用手机硬盘空间;
  }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];
} 

以上所述是小编给大家介绍的iOS视频录制(或选择)压缩及上传功能(整理),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • iOS实现视频压缩上传实例代码

    之前写过图片上传PHP服务器,今天把接口稍微改了一下,把视频上传的代码贴出来,目前上传功能已经调通,视频的压缩代码上似乎并不完善,后续会完善压缩部分的代码: - (void)convertVideoWithURL:(NSURL *)url { NSDate *date = [NSDate date]; NSDateFormatter *dateformatter = [[NSDateFormatter alloc]init]; [dateformatter setDateFormat:@"YYY

  • iOS视频录制(或选择)压缩及上传功能(整理)

    最新做的一个功能涉及到了视频的录制.压缩及上传.根据网上诸多大神的经验,终于算是调通了,但也发现了一些问题,所以把我的经验分享一下. 首先,肯定是调用一下系统的相机或相册 代码很基本: //选择本地视频 - (void)choosevideo { UIImagePickerController *ipc = [[UIImagePickerController alloc] init]; ipc.sourceType = UIImagePickerControllerSourceTypePhoto

  • Android 拍照选择图片并上传功能的实现思路(包含权限动态获取)

    作为一个Android新手,想实现手机拍照并上传的功能,经过查找资料,已实现此功能.在此记录备忘.老鸟请忽略. 一.实现思路: 1.Android手机客户端,拍照(或选择图片),然后上传到服务器. 2.服务器端接收手机端上传上来的图片. 二.实现步骤: 1.按惯例,先放效果图: 项目结构: 2.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a

  • Laravel+Layer实现图片上传功能(整理篇)

    ♩ 背景 昨天在自己的 Laravel5.5 框架项目中,希望集成 Layer 的图片上传功能 但是在 ajax(POST) 提交请求时,一直显示 500 报错 ♪ 分析 ⒈ 问题所在 最后将核心代码摘出,放到 Larvel 框架以外运行,发现代码是没有问题的,因为对 Laravel 框架接触的太浅,忽视了 CSRF 的限制 ⒉ 解决方案 一般在表单提交时,都会存放一个隐藏的输入框 <input type="hidden" name="_token" valu

  • iOS仿微信相机拍照、视频录制功能

    网上有很多自定义相机的例子,这里只是我临时写的一个iOS自定义相机(仿微信)拍照.视频录制demo,仅供参考: 用到了下面几个库: #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> 在使用的时候需要在Info.plist中把相关权限写进去: Privacy - Microphone Usage Description Privacy - Photo Library Usage

  • iOS AVCaptureSession实现视频录制功能

    本文实例为大家分享了AVCaptureSession实现视频录制功能的具体代码,供大家参考,具体内容如下 #import "RecordingVideoViewController.h" #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> @interface RecordingVideoViewController ()<AVCaptureFileOu

  • iOS实现压缩图片上传功能

    本文实例为大家分享了iOS实现压缩图片上传功能,供大家参考,具体内容如下 #pragma mark - 打开相机 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{ UIImage *image = info[UIImagePickerControllerOriginalImage]; s

  • JS移动端/H5同时选择多张图片上传并使用canvas压缩图片

    最近在做一个H5的项目,里边涉及到拍照上传图片的功能以及识别图片的功能,这里对识别图片的功能不做赘述,不属本文范畴.我在做完并上线项目后,同事跟我提了一个要求是可不可以同时选择多张图片上传,我做的时候的想法是如果给file表单加了 multiple 属性就没有办法调用手机的摄像头拍照了,如果不加,就无法同时选择多张图片,于是我就照实跟同事说了这个情况.但回头一想,单张图片可以上传,那多张图片呢?于是就有了本文的内容. HTML5定义了 FileReader 作为文件 API 的重要成员用于读取文

  • 基于AForge实现C#摄像头视频录制功能

    本文为大家分享了AForge实现C#摄像头视频录制功能的具体方法,供大家参考,具体内容如下 1. 概述 最近由于兴趣学习了下在C#上使用AForge录制摄像头视频并压缩编码.总体上来说这个第三方.net视觉开发库还是比较稳定的(AForge lib下载.离线帮助文档下载).但是由于这个第三方库维护不怎么样,导致会出现不兼容的问题.这里将这些与大家分享,希望对您有帮助. 在使用AForge第三方库录制本地视频所要使用到的类主要有这几个:FilterInfoCollection.VideoCaptu

  • iOS视频中断后台音乐播放的处理方法

    问题(App Store 用户评论反馈): 后台音乐播放器播放时启动App音乐播放器暂停,只能手动恢复 手机静音模式下视频播放没有声音 解决方案: 在播放音频时让其他程序静音,或者在其他程序的音频之上播放音频. AVAudioSession 类由 AVFoundation 框架引入.每个 iOS 应用都有一个音频会话.这个会话可以被 AVAudioSession 类的 sharedInstance 类方法访问,如下: AVAudioSession *audioSession = [AVAudio

  • Vue.js 2.0 移动端拍照压缩图片上传预览功能

    在学习和使用Vue.js 2.0 的过程中遇到不少不一样的地方,本来移动端开发H5应用,准备将mui框架和Vue.js+vue-router+vuex 全家桶结合起来使用,但是在拍照上传的实现过程中遇到了无法调用plus的H5+接口的问题,所以最后拍照上传功能还是使用input file方式里解决的.但是内心还是不甘心的,由于项目进度推进,迭代版本,所以不得不放弃,后续可能我将此功能使用调用H5+接口实现. 首先我来讲我实现这个拍照预览压缩上传的思路,准确的说应该是拍照或选择图片压缩之后预览及上

随机推荐