欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-12 19:38:22
最新做的一个功能涉及到了视频的录制、压缩及上传。根据网上诸多大神的经验,终于算是调通了,但也发现了一些问题,所以把我的经验分享一下。 首先,肯定是调用一下系统的相机或...

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

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

代码很基本:

//选择本地视频 
- (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视频录制(或选择)压缩及上传功能(整理),希望对大家有所帮助