iOS 上传本地视频或者图片(转载)

转载:https://www.cnblogs.com/zhouxihi/p/6526304.html

以下纯转载上述地址老铁的文章,只为本人记载后续使用,详情参考上边连接!!!

iOS实现视频和图片的上传

关于iOS如何实现视频和图片的上传, 我们先理清下思路

思路:

1. 如何获取图片?

2. 如何获取视频?

3. 如何把图片存到缓存路径中?

4. 如何把视频存到缓存路径中?

5. 如何上传?

接下来, 我们按照上面的思路一步一步实现

首先我们新建一个类, 用来储存每一个要上传的文件uploadModel.h

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">#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</pre>

复制代码

1. 如何获取图片?

从相册选择 或者 拍照,

这部分可以用UIImagePickerController来实现

代码如下:

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">- (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];

}</pre>

复制代码

2. 如果获取视频?

从相册选择 或者 拍摄

这部分也可以用UIImagePickerController来实现

代码:

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">- (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];

}</pre>

复制代码

3, 关于缓存, 如何把照片存入缓存目录?

这部分我们先考虑缓存目录, 一般存在Document 或者 Temp里面

我们给图片和视频各创建一个缓存目录:

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">#define PHOTOCACHEPATH [NSTemporaryDirectory() stringByAppendingPathComponent:@"photoCache"]

define VIDEOCACHEPATH [NSTemporaryDirectory() stringByAppendingPathComponent:@"videoCache"]</pre>

把UIImage存入缓存的方法:

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//将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];
    }</pre>

复制代码

4. 如何把视频存入缓存?

把视频存入缓存的方法:

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//将视频保存到缓存路径中

  • (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(@"文件保存到缓存失败");
    

    }
    }</pre>

复制代码

从缓存获取图片的方法:

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//从缓存路径获取照片

  • (UIImage *)getImageFromPath:(NSString *)path {

    NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:path]) { return [UIImage imageWithContentsOfFile:path];
    } return nil;
    }</pre>

复制代码

上传图片和视频的时候我们一般会利用当前时间给文件命名, 方法如下

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//以当前时间合成图片名称

  • (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"];
    }</pre>

复制代码

有时候需要获取视频的第一帧作为显示, 方法如下:

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//获取视频的第一帧截图, 返回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;
    }</pre>

复制代码

5. 如何上传?

下面就是上传方法:

我把服务器地址xx掉了, 大家可以改为自己的

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//上传图片和视频

  • (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;
    

    }];
    }</pre>

复制代码

这里有事先创建两个可变数组uploadArray, uploadedArray, 一个存放准要上传的内容, 一个存放上传完的内容

在准备上传后做什么操作, 可以检查两个数组的数量是否相等

最后是UIImagePickerController的协议方法

复制代码

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">#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];

}</pre>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,030评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,198评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 144,995评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,973评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,869评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,766评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,967评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,599评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,886评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,901评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,728评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,504评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,967评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,128评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,445评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,018评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,224评论 2 339