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

(0)

相关推荐

  • iOS视频录制(或选择)压缩及上传功能(整理)

    最新做的一个功能涉及到了视频的录制.压缩及上传.根据网上诸多大神的经验,终于算是调通了,但也发现了一些问题,所以把我的经验分享一下. 首先,肯定是调用一下系统的相机或相册 代码很基本: //选择本地视频 - (void)choosevideo { UIImagePickerController *ipc = [[UIImagePickerController alloc] init]; ipc.sourceType = UIImagePickerControllerSourceTypePhoto

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

    关于iOS如何实现视频和图片的上传, 我们先理清下思路,然后小编根据思路一步一步给大家详解实现过程. 思路: #1. 如何获取图片? #2. 如何获取视频? #3. 如何把图片存到缓存路径中? #4. 如何把视频存到缓存路径中? #5. 如何上传? 接下来, 我们按照上面的思路一步一步实现 首先我们新建一个类, 用来储存每一个要上传的文件uploadModel.h #import <Foundation/Foundation.h> @interface uploadModel : NSObje

  • iOS实现图片压缩的两种方法及图片压缩上传功能

    两种压缩图片的方法:压缩图片质量(Quality),压缩图片尺寸(Size). 压缩图片质量 NSData *data = UIImageJPEGRepresentation(image, compression); UIImage *resultImage = [UIImage imageWithData:data]; 通过 UIImage 和 NSData 的相互转化,减小 JPEG 图片的质量来压缩图片.UIImageJPEGRepresentation:: 第二个参数 compressi

  • vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)

    说在前面 网上有很多种文件上传的方法,根据公司最近的业务需求,要求实现多种文件的上传,在实现过程中,查阅了很多资料,最后,终于把功能实现了,开心! <template> <div> <v-header :left-text="`上传${columnName}`"></v-header> <div class="upload"> <div v-if="columnName === '视频'&q

  • Android编程实现图片的上传和下载功能示例

    本文实例讲述了Android编程实现图片的上传和下载功能.分享给大家供大家参考,具体如下: 在实现一个Android的WEB服务客户端,比如微博,论坛客户端时,经常会使用到图片的上传和下载.在这里介绍如何利用HttpClient实现图片的上传和下载功能. 1 图片上传:上传图片时,首先获得图片的路径,创建文件,并将图片转化为字节流写入到request,并发送该请求. 客户端代码: File file = new File(imageUrl); String httpUrl = httpDomai

  • 推荐三款不错的图片压缩上传插件(webuploader、localResizeIMG4、LUploader)

    涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为主,FLASH为辅,兼容 IE6+,iOS 6+, android 4+,采用大文件分片并发上传,极大的提高了文件上传效率,看了官方文档就知道,能满足你所需要的所有功能,一言以蔽之,大而全:至于缺点,大概就是插件体积太大了,自带样式文件,而且还要依赖jquery类库.详细的教程网上俯拾即是,这里我就

  • iOS视频压缩存储至本地并上传至服务器实例代码

    最近做了一个项目,我把其中的核心功能拿出来和大家分享一下,重点还是自己梳理一下. 这里关于视频转码存储我整理了两个方法,这两个方法都是针对相册内视频进行处理的. 1.该方法没有对视频进行压缩,只是将视频原封不动地从相册拿出来放到沙盒路径下,目的是拿到视频的NSData以便上传 这里我传了一个URL,这个URL有点特别,是相册文件URL,所以我说过只针对相册视频进行处理 //将原始视频的URL转化为NSData数据,写入沙盒 + (void)videoWithUrl:(NSString *)url

  • 移动前端图片压缩上传的实例

    摘要:之前在做一个小游戏平台项目,有个"用户中心"模块,就涉及到了头像上传的功能.在做移动端图片上传的时候,传的都是手机本地图片,而本地图片一般都相对比较大,拿现在的智能手机来说,平时拍很多图片都是两三兆的,如果直接这样上传,那图片就太大了,如果用户用的是移动流量,完全把图片上传显然不是一个好办法.所以上传之前进行压缩处理是必要的,在网上找了很多资料之后,尝试了很多方法,遇到了很多坑,比如安卓能够成功压缩上传图片,在ios上却上传不了,折腾了很久才发现ios的坑.一下这种已经进过实践证

  • 基于vue+axios+lrz.js微信端图片压缩上传方法

    业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能按指定尺寸压缩处理 4.上传图片可以从相册中选择或者直接拍照 遇到的坑 采用微信JSSDK上传图片 在之前开发的项目中(mui + jquery),有使用过微信JSSDK的接口上传图片,本想应该能快速迁移至此项目.事实证明编程没有简单的事: 1.按指定尺寸压缩图片 JSSDK提供的接口wx.choo

  • Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)

    使用教程(注意细看总结部分,写了几点,希望有所帮助): 1.安装插件:npm install vue-quill-editor 2.安装插件依赖:npm install quill 3.main.js文件中引入: import Vue from 'vue' import VueQuillEditor from 'vue-quill-editor' import 'quill/dist/quill.core.css' import 'quill/dist/quill.snow.css' impor

  • asp.net+jquery.form实现图片异步上传的方法(附jquery.form.js下载)

    本文实例讲述了asp.net+jquery.form实现图片异步上传的方法.分享给大家供大家参考,具体如下: 首先我们需要做准备工作: jquery 点击此处本站下载. jquery.form.js 点击此处本站下载. 页面JqueryFormTest.aspx: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="JqueryFormTest.aspx.cs" Inherits=

随机推荐