iOS實(shí)現(xiàn)視頻和圖片的上傳思路
關(guān)于iOS如何實(shí)現(xiàn)視頻和圖片的上傳, 我們先理清下思路,然后小編根據(jù)思路一步一步給大家詳解實(shí)現(xiàn)過(guò)程。
思路:
#1. 如何獲取圖片?
#2. 如何獲取視頻?
#3. 如何把圖片存到緩存路徑中?
#4. 如何把視頻存到緩存路徑中?
#5. 如何上傳?
接下來(lái), 我們按照上面的思路一步一步實(shí)現(xiàn)
首先我們新建一個(gè)類, 用來(lái)儲(chǔ)存每一個(gè)要上傳的文件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. 如何獲取圖片?
從相冊(cè)選擇 或者 拍照,
這部分可以用UIImagePickerController來(lái)實(shí)現(xiàn)
代碼如下:
- (void)actionPhoto {
UIAlertController *alertController = \
[UIAlertController alertControllerWithTitle:@""
message:@"上傳照片"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *photoAction = \
[UIAlertAction actionWithTitle:@"從相冊(cè)選擇"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"從相冊(cè)選擇");
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. 如果獲取視頻?
從相冊(cè)選擇 或者 拍攝
這部分也可以用UIImagePickerController來(lái)實(shí)現(xiàn)
代碼:
- (void)actionVideo {
UIAlertController *alertController = \
[UIAlertController alertControllerWithTitle:@""
message:@"上傳視頻"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *photoAction = \
[UIAlertAction actionWithTitle:@"從視頻庫(kù)選擇"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"從視頻庫(kù)選擇");
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, 關(guān)于緩存, 如何把照片存入緩存目錄?
這部分我們先考慮緩存目錄, 一般存在Document 或者 Temp里面
我們給圖片和視頻各創(chuàng)建一個(gè)緩存目錄:
#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(@"路徑不存在, 創(chuàng)建路徑");
[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(@"路徑不存在, 創(chuàng)建路徑");
[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;
}
上傳圖片和視頻的時(shí)候我們一般會(huì)利用當(dāng)前時(shí)間給文件命名, 方法如下
//以當(dāng)前時(shí)間合成圖片名稱
- (NSString *)getImageNameBaseCurrentTime {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"];
return [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@".JPG"];
}
//以當(dāng)前時(shí)間合成視頻名稱
- (NSString *)getVideoNameBaseCurrentTime {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"];
return [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@".MOV"];
}
有時(shí)候需要獲取視頻的第一幀作為顯示, 方法如下:
//獲取視頻的第一幀截圖, 返回UIImage
//需要導(dǎo)入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. 如何上傳?
下面就是上傳方法:
我把服務(wù)器地址xx掉了, 大家可以改為自己的
//上傳圖片和視頻
- (void)uploadImageAndMovieBaseModel:(uploadModel *)model {
//獲取文件的后綴名
NSString *extension = [model.name componentsSeparatedByString:@"."].lastObject;
//設(shè)置mimeType
NSString *mimeType;
if ([model.type isEqualToString:@"image"]) {
mimeType = [NSString stringWithFormat:@"image/%@", extension];
} else {
mimeType = [NSString stringWithFormat:@"video/%@", extension];
}
//創(chuàng)建AFHTTPSessionManager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//設(shè)置響應(yīng)文件類型為JSON類型
manager.responseSerializer = [AFJSONResponseSerializer serializer];
//初始化requestSerializer
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer.acceptableContentTypes = nil;
//設(shè)置timeout
[manager.requestSerializer setTimeoutInterval:20.0];
//設(shè)置請(qǐng)求頭類型
[manager.requestSerializer setValue:@"form/data" forHTTPHeaderField:@"Content-Type"];
//設(shè)置請(qǐng)求頭, 授權(quán)碼
[manager.requestSerializer setValue:@"YgAhCMxEehT4N/DmhKkA/M0npN3KO0X8PMrNl17+hogw944GDGpzvypteMemdWb9nlzz7mk1jBa/0fpOtxeZUA==" forHTTPHeaderField:@"Authentication"];
//上傳服務(wù)器接口
NSString *url = [NSString stringWithFormat:@"http://xxxxx.xxxx.xxx.xx.x"];
//開(kāi)始上傳
[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(@"上傳進(jìn)度: %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;
}];
}
這里有事先創(chuàng)建兩個(gè)可變數(shù)組uploadArray, uploadedArray, 一個(gè)存放準(zhǔn)要上傳的內(nèi)容, 一個(gè)存放上傳完的內(nèi)容
在準(zhǔn)備上傳后做什么操作, 可以檢查兩個(gè)數(shù)組的數(shù)量是否相等
最后是UIImagePickerController的協(xié)議方法
#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];
//將照片存入相冊(cè)
if (tempImage) {
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
//將照片存入相冊(cè)
NSLog(@"將照片存入相冊(cè)");
UIImageWriteToSavedPhotosAlbum(tempImage, self, nil, nil);
}
//獲取圖片名稱
NSLog(@"獲取圖片名稱");
NSString *imageName = [self getImageNameBaseCurrentTime];
NSLog(@"圖片名稱: %@", imageName);
//將圖片存入緩存
NSLog(@"將圖片寫(xiě)入緩存");
[self saveImage:tempImage
toCachePath:[PHOTOCACHEPATH stringByAppendingPathComponent:imageName]];
//創(chuàng)建uploadModel
NSLog(@"創(chuàng)建model");
uploadModel *model = [[uploadModel alloc] init];
model.path = [PHOTOCACHEPATH stringByAppendingPathComponent:imageName];
model.name = imageName;
model.type = @"image";
model.isUploaded = NO;
//將模型存入待上傳數(shù)組
NSLog(@"將Model存入待上傳數(shù)組");
[self.uploadArray addObject:model];
}
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
//如果是拍攝的視頻, 則把視頻保存在系統(tǒng)多媒體庫(kù)中
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]];
//創(chuàng)建uploadmodel
uploadModel *model = [[uploadModel alloc] init];
model.path = [VIDEOCACHEPATH stringByAppendingPathComponent:mediaName];
model.name = mediaName;
model.type = @"moive";
model.isUploaded = NO;
//將model存入待上傳數(shù)組
[self.uploadArray addObject:model];
}
//[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
以上所述是小編給大家介紹的iOS實(shí)現(xiàn)視頻和圖片的上傳思路,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- iOS開(kāi)發(fā)之獲取系統(tǒng)相冊(cè)中的圖片與視頻教程(內(nèi)帶url轉(zhuǎn)換)
- IOS實(shí)現(xiàn)視頻動(dòng)畫(huà)效果的啟動(dòng)圖
- 淺析iOS中視頻播放的幾種方案
- iOS視頻錄制(或選擇)壓縮及上傳功能(整理)
- iOS仿微信相機(jī)拍照、視頻錄制功能
- 詳解iOS應(yīng)用中播放本地視頻以及選取本地音頻的組件用法
- iOS中視頻播放器的簡(jiǎn)單封裝詳解
- iOS中讀取照片庫(kù)及保存圖片或視頻到照片庫(kù)的要點(diǎn)解析
- iOS 本地視頻和網(wǎng)絡(luò)視頻流播放實(shí)例代碼
- iOS視頻中斷后臺(tái)音樂(lè)播放的處理方法
相關(guān)文章
僅幾行iOS代碼限制TextField輸入長(zhǎng)度
這篇文章主要為大家詳細(xì)介紹了通過(guò)幾行iOS代碼限制TextField輸入長(zhǎng)度的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
iOS9 系統(tǒng)分享調(diào)用之UIActivityViewController
UIActivityViewController類是一個(gè)標(biāo)準(zhǔn)的view controller,通個(gè)使用這個(gè)controller,你的應(yīng)用程序就可以提供各種服務(wù)。本文給大家介紹iOS9 系統(tǒng)分享調(diào)用之UIActivityViewController,感興趣的朋友一起學(xué)習(xí)吧2015-11-11
IOS 實(shí)現(xiàn)一個(gè)死鎖導(dǎo)致 UI 假死的例子
這篇文章主要介紹了IOS 實(shí)現(xiàn)一個(gè)死鎖導(dǎo)致 UI 假死的例子的相關(guān)資料,需要的朋友可以參考下2016-12-12
iOS開(kāi)發(fā)之路--微博“更多”頁(yè)面
本文是IOS開(kāi)發(fā)之路系列文章第五篇,主要講訴了,如何制作微博的更多頁(yè)面,并附上效果圖及源碼,需要的朋友可以參考下,希望能有所幫助2014-08-08
IOS 開(kāi)發(fā)APP之關(guān)于時(shí)間處理詳細(xì)介紹
這篇文章主要介紹了IOS 開(kāi)發(fā)APP之關(guān)于時(shí)間處理詳細(xì)介紹的相關(guān)資料,開(kāi)發(fā)APP 不僅需要對(duì)API的調(diào)用還需要對(duì)時(shí)間相關(guān)的各種API之間的差別,再因場(chǎng)景而異去設(shè)計(jì)相應(yīng)的機(jī)制,需要的朋友可以參考下2016-12-12
實(shí)例講解如何在iOS應(yīng)用開(kāi)發(fā)中使用設(shè)計(jì)模式中的代理模式
這篇文章主要介紹了實(shí)例講解如何在iOS應(yīng)用開(kāi)發(fā)中使用設(shè)計(jì)模式中的代理模式,示例為傳統(tǒng)的Objective-C語(yǔ)言代碼,需要的朋友可以參考下2016-03-03
iOS App連續(xù)閃退時(shí)上報(bào)crash日志的方法詳解
iOS App 有時(shí)可能遇到啟動(dòng)必 crash 的絕境:每次打開(kāi) App 都閃退,無(wú)法正常使用App。下面這篇文章主要給大家介紹了iOS App連續(xù)閃退時(shí)上報(bào)crash日志的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2018-04-04

