iOS 上傳本地視頻或者圖片(轉(zhuǎn)載)

轉(zhuǎn)載:https://www.cnblogs.com/zhouxihi/p/6526304.html

以下純轉(zhuǎn)載上述地址老鐵的文章,只為本人記載后續(xù)使用,詳情參考上邊連接!!!

iOS實(shí)現(xiàn)視頻和圖片的上傳

關(guān)于iOS如何實(shí)現(xiàn)視頻和圖片的上傳, 我們先理清下思路

思路:

1. 如何獲取圖片?

2. 如何獲取視頻?

3. 如何把圖片存到緩存路徑中?

4. 如何把視頻存到緩存路徑中?

5. 如何上傳?

接下來(lái), 我們按照上面的思路一步一步實(shí)現(xiàn)

首先我們新建一個(gè)類(lèi), 用來(lái)儲(chǔ)存每一個(gè)要上傳的文件uploadModel.h

復(fù)制代碼

<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>

復(fù)制代碼

1. 如何獲取圖片?

從相冊(cè)選擇 或者 拍照,

這部分可以用UIImagePickerController來(lái)實(shí)現(xiàn)

代碼如下:

復(fù)制代碼

<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:@"從相冊(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];

}</pre>

復(fù)制代碼

2. 如果獲取視頻?

從相冊(cè)選擇 或者 拍攝

這部分也可以用UIImagePickerController來(lái)實(shí)現(xiàn)

代碼:

復(fù)制代碼

<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:@"從視頻庫(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];

}</pre>

復(fù)制代碼

3, 關(guān)于緩存, 如何把照片存入緩存目錄?

這部分我們先考慮緩存目錄, 一般存在Document 或者 Temp里面

我們給圖片和視頻各創(chuàng)建一個(gè)緩存目錄:

<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存入緩存的方法:

復(fù)制代碼

<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(@"路徑不存在, 創(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];
    }</pre>

復(fù)制代碼

4. 如何把視頻存入緩存?

把視頻存入緩存的方法:

復(fù)制代碼

<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(@"路徑不存在, 創(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(@"文件保存到緩存失敗");
    

    }
    }</pre>

復(fù)制代碼

從緩存獲取圖片的方法:

復(fù)制代碼

<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>

復(fù)制代碼

上傳圖片和視頻的時(shí)候我們一般會(huì)利用當(dāng)前時(shí)間給文件命名, 方法如下

復(fù)制代碼

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//以當(dāng)前時(shí)間合成圖片名稱(chēng)

  • (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í)間合成視頻名稱(chēng)

  • (NSString *)getVideoNameBaseCurrentTime {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"]; return [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@".MOV"];
    }</pre>

復(fù)制代碼

有時(shí)候需要獲取視頻的第一幀作為顯示, 方法如下:

復(fù)制代碼

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">//獲取視頻的第一幀截圖, 返回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;
    }</pre>

復(fù)制代碼

5. 如何上傳?

下面就是上傳方法:

我把服務(wù)器地址xx掉了, 大家可以改為自己的

復(fù)制代碼

<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; //設(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)文件類(lèi)型為JSON類(lèi)型
    manager.responseSerializer = [AFJSONResponseSerializer serializer]; //初始化requestSerializer
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];

    manager.responseSerializer.acceptableContentTypes = nil; //設(shè)置timeout
    [manager.requestSerializer setTimeoutInterval:20.0]; //設(shè)置請(qǐng)求頭類(lèi)型
    [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;
    

    }];
    }</pre>

復(fù)制代碼

這里有事先創(chuàng)建兩個(gè)可變數(shù)組uploadArray, uploadedArray, 一個(gè)存放準(zhǔn)要上傳的內(nèi)容, 一個(gè)存放上傳完的內(nèi)容

在準(zhǔn)備上傳后做什么操作, 可以檢查兩個(gè)數(shù)組的數(shù)量是否相等

最后是UIImagePickerController的協(xié)議方法

復(fù)制代碼

<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]; //獲取用戶(hù)選擇或拍攝的是照片還是視頻
    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);
    } //獲取圖片名稱(chēng)
    NSLog(@"獲取圖片名稱(chēng)");
    NSString *imageName = [self getImageNameBaseCurrentTime];
    NSLog(@"圖片名稱(chēng): %@", 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(@"視頻保存失敗");
              }
          }];
      } //生成視頻名稱(chēng)
      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];

}</pre>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓮顽,老刑警劉巖激率,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欣尼,死亡現(xiàn)場(chǎng)離奇詭異率碾,居然都是意外死亡矩动,警方通過(guò)查閱死者的電腦和手機(jī)等限,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)爸吮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人望门,你說(shuō)我怎么就攤上這事形娇。” “怎么了筹误?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵桐早,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我厨剪,道長(zhǎng)哄酝,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任祷膳,我火速辦了婚禮陶衅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘直晨。我一直安慰自己搀军,他們只是感情好膨俐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著罩句,像睡著了一般焚刺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上门烂,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天乳愉,我揣著相機(jī)與錄音,去河邊找鬼诅福。 笑死匾委,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的氓润。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼薯鳍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼咖气!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起挖滤,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤崩溪,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后斩松,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體伶唯,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年惧盹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乳幸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钧椰,死狀恐怖粹断,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嫡霞,我是刑警寧澤瓶埋,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站诊沪,受9級(jí)特大地震影響养筒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜端姚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一晕粪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寄锐,春花似錦兵多、人聲如沸尖啡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)衅斩。三九已至,卻和暖如春怠褐,著一層夾襖步出監(jiān)牢的瞬間畏梆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工奈懒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奠涌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓磷杏,卻偏偏與公主長(zhǎng)得像溜畅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子极祸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355