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];
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM