首页 > 系统 > iOS > 正文

iOS实现视频和图片的上传思路

2020-07-26 02:54:11
字体:
来源:转载
供稿:网友

关于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 *)pickerdidFinishPickingMediaWithInfo:(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实现视频和图片的上传思路,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表