美文网首页汽车公司可能用到的知识点
iOS 上传本地视频或者图片(转载)

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

作者: 辛乐 | 来源:发表于2020-05-11 17:41 被阅读0次

    转载: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>

    相关文章

      网友评论

        本文标题:iOS 上传本地视频或者图片(转载)

        本文链接:https://www.haomeiwen.com/subject/euqpnhtx.html