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视频录制(或选择)压缩及上传功能(整理),希望对大家有所帮助
下一篇: java数据结构之希尔排序