iOS实现视频和图片的上传思路
程序员文章站
2023-12-20 16:46:10
关于ios如何实现视频和图片的上传, 我们先理清下思路,然后小编根据思路一步一步给大家详解实现过程。
思路:
#1. 如何获取图片?
#2. 如何获取视频...
关于ios如何实现视频和图片的上传, 我们先理清下思路,然后小编根据思路一步一步给大家详解实现过程。
思路:
#1. 如何获取图片?
#2. 如何获取视频?
#3. 如何把图片存到缓存路径中?
#4. 如何把视频存到缓存路径中?
#5. 如何上传?
接下来, 我们按照上面的思路一步一步实现
首先我们新建一个类, 用来储存每一个要上传的文件uploadmodel.h
#import <foundation/foundation.h> @interface uploadmodel : nsobject @property (nonatomic, strong) nsstring *path; @property (nonatomic, strong) nsstring *type; @property (nonatomic, strong) nsstring *name; @property (nonatomic, assign) bool isuploaded; @end
#1. 如何获取图片?
从相册选择 或者 拍照,
这部分可以用uiimagepickercontroller来实现
代码如下:
- (void)actionphoto { uialertcontroller *alertcontroller = \ [uialertcontroller alertcontrollerwithtitle:@"" message:@"上传照片" preferredstyle:uialertcontrollerstyleactionsheet]; uialertaction *photoaction = \ [uialertaction actionwithtitle:@"从相册选择" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) { nslog(@"从相册选择"); self.imagepicker.sourcetype = uiimagepickercontrollersourcetypephotolibrary; self.imagepicker.mediatypes = @[(nsstring *)kuttypeimage]; self.imagepicker.allowsediting = yes; [self presentviewcontroller:self.imagepicker animated:yes completion:nil]; }]; uialertaction *cameraaction = \ [uialertaction actionwithtitle:@"拍照" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) { nslog(@"拍照"); if ([uiimagepickercontroller issourcetypeavailable:uiimagepickercontrollersourcetypecamera]) { self.imagepicker.sourcetype = uiimagepickercontrollersourcetypecamera; self.imagepicker.cameracapturemode = uiimagepickercontrollercameracapturemodephoto; self.imagepicker.cameradevice = uiimagepickercontrollercameradevicerear; self.imagepicker.allowsediting = yes; [self presentviewcontroller:self.imagepicker animated:yes completion:nil]; } }]; uialertaction *cancelaction = \ [uialertaction actionwithtitle:@"取消" style:uialertactionstylecancel handler:^(uialertaction * _nonnull action) { nslog(@"取消"); }]; [alertcontroller addaction:photoaction]; [alertcontroller addaction:cameraaction]; [alertcontroller addaction:cancelaction]; [self presentviewcontroller:alertcontroller animated:yes completion:nil]; }
#2. 如果获取视频?
从相册选择 或者 拍摄
这部分也可以用uiimagepickercontroller来实现
代码:
- (void)actionvideo { uialertcontroller *alertcontroller = \ [uialertcontroller alertcontrollerwithtitle:@"" message:@"上传视频" preferredstyle:uialertcontrollerstyleactionsheet]; uialertaction *photoaction = \ [uialertaction actionwithtitle:@"从视频库选择" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) { nslog(@"从视频库选择"); self.imagepicker.sourcetype = uiimagepickercontrollersourcetypephotolibrary; self.imagepicker.mediatypes = @[(nsstring *)kuttypemovie]; self.imagepicker.allowsediting = no; [self presentviewcontroller:self.imagepicker animated:yes completion:nil]; }]; uialertaction *cameraaction = \ [uialertaction actionwithtitle:@"录像" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) { nslog(@"录像"); self.imagepicker.sourcetype = uiimagepickercontrollersourcetypecamera; self.imagepicker.cameradevice = uiimagepickercontrollercameradevicerear; self.imagepicker.mediatypes = [uiimagepickercontroller availablemediatypesforsourcetype:uiimagepickercontrollersourcetypecamera]; self.imagepicker.videoquality = uiimagepickercontrollerqualitytype640x480; self.imagepicker.cameracapturemode = uiimagepickercontrollercameracapturemodevideo; self.imagepicker.allowsediting = yes; [self presentviewcontroller:self.imagepicker animated:yes completion:nil]; }]; uialertaction *cancelaction = \ [uialertaction actionwithtitle:@"取消" style:uialertactionstylecancel handler:^(uialertaction * _nonnull action) { nslog(@"取消"); }]; [alertcontroller addaction:photoaction]; [alertcontroller addaction:cameraaction]; [alertcontroller addaction:cancelaction]; [self presentviewcontroller:alertcontroller animated:yes completion:nil]; }
#3, 关于缓存, 如何把照片存入缓存目录?
这部分我们先考虑缓存目录, 一般存在document 或者 temp里面
我们给图片和视频各创建一个缓存目录:
#define photocachepath [nstemporarydirectory() stringbyappendingpathcomponent:@"photocache"] #define videocachepath [nstemporarydirectory() stringbyappendingpathcomponent:@"videocache"]
把uiimage存入缓存的方法:
//将image保存到缓存路径中 - (void)saveimage:(uiimage *)image tocachepath:(nsstring *)path { nsfilemanager *filemanager = [nsfilemanager defaultmanager]; if (![filemanager fileexistsatpath:photocachepath]) { nslog(@"路径不存在, 创建路径"); [filemanager createdirectoryatpath:photocachepath withintermediatedirectories:yes attributes:nil error:nil]; } else { nslog(@"路径存在"); } //[uiimagepngrepresentation(image) writetofile:path atomically:yes]; [uiimagejpegrepresentation(image, 1) writetofile:path atomically:yes]; }
4. 如何把视频存入缓存?
把视频存入缓存的方法:
//将视频保存到缓存路径中 - (void)savevideofrompath:(nsstring *)videopath tocachepath:(nsstring *)path { nsfilemanager *filemanager = [nsfilemanager defaultmanager]; if (![filemanager fileexistsatpath:videocachepath]) { nslog(@"路径不存在, 创建路径"); [filemanager createdirectoryatpath:videocachepath withintermediatedirectories:yes attributes:nil error:nil]; } else { nslog(@"路径存在"); } nserror *error; [filemanager copyitematpath:videopath topath:path error:&error]; if (error) { nslog(@"文件保存到缓存失败"); } }
从缓存获取图片的方法:
//从缓存路径获取照片 - (uiimage *)getimagefrompath:(nsstring *)path { nsfilemanager *filemanager = [nsfilemanager defaultmanager]; if ([filemanager fileexistsatpath:path]) { return [uiimage imagewithcontentsoffile:path]; } return nil; }
上传图片和视频的时候我们一般会利用当前时间给文件命名, 方法如下
//以当前时间合成图片名称 - (nsstring *)getimagenamebasecurrenttime { nsdateformatter *dateformatter = [[nsdateformatter alloc] init]; [dateformatter setdateformat:@"yyyy-mm-dd hh-mm-ss"]; return [[dateformatter stringfromdate:[nsdate date]] stringbyappendingstring:@".jpg"]; } //以当前时间合成视频名称 - (nsstring *)getvideonamebasecurrenttime { nsdateformatter *dateformatter = [[nsdateformatter alloc] init]; [dateformatter setdateformat:@"yyyy-mm-dd hh-mm-ss"]; return [[dateformatter stringfromdate:[nsdate date]] stringbyappendingstring:@".mov"]; }
有时候需要获取视频的第一帧作为显示, 方法如下:
//获取视频的第一帧截图, 返回uiimage //需要导入avfoundation.h - (uiimage*) getvideopreviewimagewithpath:(nsurl *)videopath { avurlasset *asset = [[avurlasset alloc] initwithurl:videopath options:nil]; avassetimagegenerator *gen = [[avassetimagegenerator alloc] initwithasset:asset]; gen.appliespreferredtracktransform = yes; cmtime time = cmtimemakewithseconds(0.0, 600); nserror *error = nil; cmtime actualtime; cgimageref image = [gen copycgimageattime:time actualtime:&actualtime error:&error]; uiimage *img = [[uiimage alloc] initwithcgimage:image]; return img; }
5. 如何上传?
下面就是上传方法:
我把服务器地址xx掉了, 大家可以改为自己的
//上传图片和视频 - (void)uploadimageandmoviebasemodel:(uploadmodel *)model { //获取文件的后缀名 nsstring *extension = [model.name componentsseparatedbystring:@"."].lastobject; //设置mimetype nsstring *mimetype; if ([model.type isequaltostring:@"image"]) { mimetype = [nsstring stringwithformat:@"image/%@", extension]; } else { mimetype = [nsstring stringwithformat:@"video/%@", extension]; } //创建afhttpsessionmanager afhttpsessionmanager *manager = [afhttpsessionmanager manager]; //设置响应文件类型为json类型 manager.responseserializer = [afjsonresponseserializer serializer]; //初始化requestserializer manager.requestserializer = [afhttprequestserializer serializer]; manager.responseserializer.acceptablecontenttypes = nil; //设置timeout [manager.requestserializer settimeoutinterval:20.0]; //设置请求头类型 [manager.requestserializer setvalue:@"form/data" forhttpheaderfield:@"content-type"]; //设置请求头, 授权码 [manager.requestserializer setvalue:@"ygahcmxeeht4n/dmhkka/m0npn3ko0x8pmrnl17+hogw944gdgpzvyptememdwb9nlzz7mk1jba/0fpotxezua==" forhttpheaderfield:@"authentication"]; //上传服务器接口 nsstring *url = [nsstring stringwithformat:@"http://xxxxx.xxxx.xxx.xx.x"]; //开始上传 [manager post:url parameters:nil constructingbodywithblock:^(id<afmultipartformdata> _nonnull formdata) { nserror *error; bool success = [formdata appendpartwithfileurl:[nsurl fileurlwithpath:model.path] name:model.name filename:model.name mimetype:mimetype error:&error]; if (!success) { nslog(@"appendpartwithfileurl error: %@", error); } } progress:^(nsprogress * _nonnull uploadprogress) { nslog(@"上传进度: %f", uploadprogress.fractioncompleted); } success:^(nsurlsessiondatatask * _nonnull task, id _nullable responseobject) { nslog(@"成功返回: %@", responseobject); model.isuploaded = yes; [self.uploadedarray addobject:model]; } failure:^(nsurlsessiondatatask * _nullable task, nserror * _nonnull error) { nslog(@"上传失败: %@", error); model.isuploaded = no; }]; }
这里有事先创建两个可变数组uploadarray, uploadedarray, 一个存放准要上传的内容, 一个存放上传完的内容
在准备上传后做什么操作, 可以检查两个数组的数量是否相等
最后是uiimagepickercontroller的协议方法
#pragma mark - uiimagepickerdelegate methods - (void)imagepickercontroller:(uiimagepickercontroller *)picker didfinishpickingmediawithinfo:(nsdictionary<nsstring *,id> *)info { [picker dismissviewcontrolleranimated:yes completion:nil]; //获取用户选择或拍摄的是照片还是视频 nsstring *mediatype = info[uiimagepickercontrollermediatype]; if ([mediatype isequaltostring:(nsstring *)kuttypeimage]) { //获取编辑后的照片 nslog(@"获取编辑后的好片"); uiimage *tempimage = info[uiimagepickercontrollereditedimage]; //将照片存入相册 if (tempimage) { if (picker.sourcetype == uiimagepickercontrollersourcetypecamera) { //将照片存入相册 nslog(@"将照片存入相册"); uiimagewritetosavedphotosalbum(tempimage, self, nil, nil); } //获取图片名称 nslog(@"获取图片名称"); nsstring *imagename = [self getimagenamebasecurrenttime]; nslog(@"图片名称: %@", imagename); //将图片存入缓存 nslog(@"将图片写入缓存"); [self saveimage:tempimage tocachepath:[photocachepath stringbyappendingpathcomponent:imagename]]; //创建uploadmodel nslog(@"创建model"); uploadmodel *model = [[uploadmodel alloc] init]; model.path = [photocachepath stringbyappendingpathcomponent:imagename]; model.name = imagename; model.type = @"image"; model.isuploaded = no; //将模型存入待上传数组 nslog(@"将model存入待上传数组"); [self.uploadarray addobject:model]; } } else if ([mediatype isequaltostring:(nsstring *)kuttypemovie]) { if (picker.sourcetype == uiimagepickercontrollersourcetypecamera) { //如果是拍摄的视频, 则把视频保存在系统多媒体库中 nslog(@"video path: %@", info[uiimagepickercontrollermediaurl]); alassetslibrary *library = [[alassetslibrary alloc] init]; [library writevideoatpathtosavedphotosalbum:info[uiimagepickercontrollermediaurl] completionblock:^(nsurl *asseturl, nserror *error) { if (!error) { nslog(@"视频保存成功"); } else { nslog(@"视频保存失败"); } }]; } //生成视频名称 nsstring *medianame = [self getvideonamebasecurrenttime]; nslog(@"medianame: %@", medianame); //将视频存入缓存 nslog(@"将视频存入缓存"); [self savevideofrompath:info[uiimagepickercontrollermediaurl] tocachepath:[videocachepath stringbyappendingpathcomponent:medianame]]; //创建uploadmodel uploadmodel *model = [[uploadmodel alloc] init]; model.path = [videocachepath stringbyappendingpathcomponent:medianame]; model.name = medianame; model.type = @"moive"; model.isuploaded = no; //将model存入待上传数组 [self.uploadarray addobject:model]; } //[picker dismissviewcontrolleranimated:yes completion:nil]; } - (void)imagepickercontrollerdidcancel:(uiimagepickercontroller *)picker { [picker dismissviewcontrolleranimated:yes completion:nil]; }
以上所述是小编给大家介绍的ios实现视频和图片的上传思路,希望对大家有所帮助