ios 上传视频或图片
关于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, ) 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, );
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 上传视频或图片的更多相关文章
- 微信小程序里如何用阿里云上传视频,图片。。
纯手写,踩了半天多的坑干出来了... 网上也有对于阿里云如何在微信小程序里使用,但是很不全,包括阿里云文档的最佳实践里. 话不多说上代码了. upvideo(){ var aliOssParams = ...
- 修复dtcms5.0后台管理编辑器上传视频和图片被过滤问题
1.原程序代码调用上传接口文件路径更改为父节点相对路径: 2.修复ueditor.config.js配置: img: ['src', 'alt', 'title', 'width', 'height' ...
- 前端上传视频、图片、文件等大文件 组件Plupload使用指南
demo:https://blog.csdn.net/qq_30100043/article/details/78491993 Plupload上传插件中文帮助文档网址:http://www.phpi ...
- MVC与webservice上传文件(图片和视频),希望帮且到一些朋友
最近做一个项目,要把图片和视频传到服务器上(网站与图片服务器分开),在网上找了好久,没找到完整的资料. 自己也折腾了半天,才把完整的代码实现完.可能好多朋友都有实现过,没分享代码吧,写得不好希望不要见 ...
- 七牛云上传视频并截取第一帧为图片(js实现)
本文出自APICloud官方论坛, 感谢论坛版主 东冥羽的分享. 七牛云上传视频并截取第一帧作为视频的封面图. 使用js上传,模块videoPlayer截取第一帧(有专门的截图模块,但是我使用的有点问 ...
- 微信小程序云开发-云存储-上传文件(图片/视频)到云存储 精简代码
说明 图片/视频这类文件是从客户端会话选择文件. 一.wxml文件添加if切换显示 <!--上传文件到云存储--> <button bindtap="chooseImg&q ...
- PHP后台代码 及 iOS客户端--AF实现上传视频
//视频转换为MP4 //转码操作... _hud.mode = MBProgressHUDModeIndeterminate; _hud.labelText = @"转码中..." ...
- dropzonejs中文翻译手册 DropzoneJS是一个提供文件拖拽上传并且提供图片预览的开源类库.
http://wxb.github.io/dropzonejs.com.zh-CN/dropzonezh-CN/ 由于项目需要,完成一个web的图片拖拽上传,也就顺便学习和了解了一下前端的比较新的技术 ...
- 百度上传工具webuploader,图片上传附加参数
项目中需要上传视频,图片等资源.最先做的是上传图片,开始在网上找了一款野鸡插件,可以实现图片上传预览(无需传到后台).但是最近这个插件出了莫名的问题,不易修复,一怒之下,还是决定找个大点的,靠谱的插件 ...
随机推荐
- 深入理解React虚拟DOM
一.什么是虚拟DOM 虚拟DOM可以看做一棵模拟了DOM树的JavaScript对象树.比如: var element = { element: 'ul', props: { id:"uli ...
- SAP销售订单屏幕增强行项目屏幕增强
1.在vbap表中 append一个自定义结构,如下图: 2.TCODE:SE80 程序名:SAPMV45A 屏幕:8459 如图: 3.标记增强的屏幕字段 4.屏幕增强的位置 *& ...
- Spring @Transactional 浅谈
一般当我们在一个方法里面操作多个数据对象的可持久化操作时,我们通常这些操作能够成功一起事务提交成功.默认情况下,数据库处于自动提交模式.每一条语句处于一个单独的事务中,在这条语句执行完毕时,如果执行成 ...
- nginx 如何配置来获取用户真实IP
- 使用paramiko报错:CryptographyDeprecationWarning: Support for unsafe construction of public numbers from encoded data will be removed in a future version. Please use EllipticCurvePublicKey.from_encoded_poi
1.paramiko不支持cryptography-2.6.1 pip3 uninstall cryptography==2.6.1 2.paramiko 支持cryptography-2.4.2 p ...
- SQL Server中的日期,时间组合查询
如图所示,Jdate和Jdate2是两个分开的字段,一个是date类型,存储日期,一个是time(0)类型,存储具体时间 现在有这样的要求,就是获得(Jdate和Jdate2组合起来的日期时间)在(当 ...
- JavaScript事件对象与事件的委托
事件对象 包含事件相关的信息,如鼠标.时间.触发的DOM对象等 js默认将事件对象封装好,并自动的以参数的形式,传递给事件处理函数的第1个参数,如下: document.getElementsByTa ...
- Python Map, Filter and Reduce
所属网站分类: python基础 > 函数 作者:慧雅 原文链接: http://www.pythonheidong.com/blog/article/21/ 来源:python黑洞网 www. ...
- Python3中的列表用法,看这一篇就够了
类似C语言中的列表用法 ---------------------------------------------------------------------------------------- ...
- 动态规划:HDU-2955-0-1背包问题:Robberies
解题心得: 这题涉及概率问题,所以要运用概率的知识进行解答.题目要求不被抓到的概率,但是给出的是被抓到的概率,所要用1减去后得到答案.最好使用double类型,避免精度问题导致WA. 先算出可以抢劫的 ...