關于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
從相冊選擇 或者 拍照,
這部分可以用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];}
從相冊選擇 或者 拍攝
這部分也可以用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];}
這部分我們先考慮緩存目錄, 一般存在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];}
把視頻存入緩存的方法:
//將視頻保存到緩存路徑中- (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;}
下面就是上傳方法:
我把服務器地址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];}
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
表格插入圖片不能浮于文字下方?在Excel中,您可以 不要把圖片放在文字的底部,只能用插入-背景的方法。如下所示:1.打開EXCexcel中文本標注框怎么翻轉?Excel單元格中的文字是反轉的,可以通過使用文本框,旋轉180度來實現。具體步驟如下:1.打開要操作的EXCEL表格,在插入工具欄中找到,點擊 "文本框和。2.在表格中畫一個大小合適的文本框,輸入需要反轉的文本內容,然后點擊文本框上方的綠...
PS如何給照片換發型?換造型在PS里面算是一個中等難度的你操作了,要完全掌握的東西也少的,要想能做到這個效果,必須你要有兩張圖片,一個肯定是你要換發型的人物,還必須兩張你要換的發型的圖片,利用蒙版,調色的一些方法參與水配,這個要看圖片,相同的圖片方法也是一樣的,而且要注重任務的角度,這是一個很靈話的工作,沒有什么固定設置的方法,而要看你要想做的圖是怎樣的。ps如何直接挪動頭發?ps是可以就挪動身體...
ipad怎樣打開mmap?Mmap文件可以用MindManager軟件打開。JetMindManager是創建、管理和交換想法的通用標準。其可視化繪圖軟件具有直觀、友好的用戶界面和豐富的功能,將幫助您有序地組織您的想法、資源和項目進度。MindManager也是一款簡單易用的項目管理軟件,可以提高項目團隊的工作效率和團隊成員之間的協作。作為一種組織資源和管理項目的方法,它可以從腦圖的核心分支中導出...