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,图片上传附加参数
项目中需要上传视频,图片等资源.最先做的是上传图片,开始在网上找了一款野鸡插件,可以实现图片上传预览(无需传到后台).但是最近这个插件出了莫名的问题,不易修复,一怒之下,还是决定找个大点的,靠谱的插件 ...
随机推荐
- 51nod——2476 小b和序列(预处理 思维)
对于每一个元素,预处理出它作为最小值,两边可以作用到的最大位置.比如下标∈[0,8]的这个数组:1 8 6 2 5 4 3 8 7,1可以作用到所有区间,2可以作用到区间[1,8],第一个8可以作用到 ...
- 【C++学习笔记】 链式前向星
链式前向星是一种常见的储存图的方式(是前向星存图法的优化版本),支持增边和查询,但不支持删边(如果想要删除指定的边建议用邻接矩阵). 储存方式 首先定义数组 head[ i ] 来储存从节点 i 出发 ...
- 三十一、MySQL 及 SQL 注入
MySQL 及 SQL 注入 如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题. 本章节将为大家介绍如何防止SQL注入,并通过脚本来过滤SQL中注入 ...
- 入门学习Linux常用必会命令实例详解
Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令.要想真正理解Linux系统, ...
- 打开POST传参的弹出窗口
//穿件 function openPostPopWindow(url,param,target){ var $form = $("<form></form>&quo ...
- 【解决】ERROR in xxx.js from UglifyJs
当我们运行打包脚本npm run build或者打包iosweexpack build ios有可能会遇到以下报错 ERROR in index.js from UglifyJs (25 分)
A1025 PAT Ranking (25)(25 分) Programming Ability Test (PAT) is organized by the College of Computer ...
- (HTML)写导航感悟
代码要规范,路径要写全 如: .div1 ul li a:link { text-decoration: none; color: white; } .div1 ul li a:visited { t ...
- Linux系统自启动脚
只需编辑/etc/init.d/rc.local文件,在最后加上你的脚本即可. 比如:我已经编写了一个脚本shell.sh,存放在/home/mars704/Desktop/ 下面在终端输入 gedi ...