視頻的錄制、保存、壓縮以及base64轉碼

這里沒有主要是說下和視頻相關的小技術點,都是一些相對比較基本的,但是對于沒有怎么和視頻打交道的人而言,找一些資料還不是很方便,所以今天就沒事白這些東西給稍微整理了一下。
先看看視頻的錄制,這里主要說的是使用系統的UIImagePickerController這個類進行視頻的錄制。注意:導入這個框架才能錄制視頻#import<MobileCoreServices/MobileCoreServices.h>這個框架后才能播放進入系統的錄制視頻界面。

 //1、判斷照相機是否可用  不可用就直接return  一般都是這樣
    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        return;
    }
    //2.初始化
    UIImagePickerController *picker = [UIImagePickerController new];
    //3.設置類型
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    //通常4和5是一塊設置的
    //4.設置媒體類型  默認是拍照
    picker.mediaTypes = @[(NSString *)kUTTypeMovie];
    //注意:如果是UIImagePickerControllerSourceTypePhotoLibrary設置下面的兩句會崩潰
  //5.設置攝像機模式
  picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo; //6.設置視頻質量
//    picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
    //7.設置代理
    picker.delegate = self;
    //8.模態彈出
    [self presentViewController:picker animated:YES completion:nil];

再看一下錄制的視頻如何保存到本地。注意:保存視頻到本地 需要這個資源庫<AssetsLibrary/AssetsLibrary.h>

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    //1.判斷是否是視頻的媒體類型
    NSString *mediaType = info[UIImagePickerControllerMediaType];
    //2.保存視頻到本地   需要這個資源庫<AssetsLibrary/AssetsLibrary.h>
    //必須做這個判斷
   if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
      //這個已經過期了  iOS9需要換成PHPhotoLibrary
      //2.1創建ALAssetsLibrary對象
      ALAssetsLibrary *assetsLibrary = [ALAssetsLibrary new];
      //2.2 這個url是指要保存的視頻的url 
       [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error) {           
      }];
  }
    [picker dismissViewControllerAnimated:YES completion:nil];
}

下面是視頻的壓縮的一個類方法,以及刪除壓縮后視頻的方法。代碼內部有十分詳細的注釋。說明一下第一個方法中傳入的sourceVideoPathString是這樣獲取的。在(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info這個方法中,通過
self.videoPathString = (NSString *)([info[@"UIImagePickerControllerMediaURL"] path]);這樣的形式獲取到路徑。

+ (void)compressVideoWithSourceVideoPathString:(NSString *)sourceVideoPathString
                                  CompressType:(NSString *)compressType
                          CompressSuccessBlock:(SuccessBlock)compressSuccessBlock
                           CompressFailedBlock:(FailedBlock)compressFailedBlock
                       CompressNotSupportBlock:(NotSupportBlock)compressNotSupportBlock {
    
    // 源視頻路徑
    NSURL *sourceVideoPathUrl = [NSURL fileURLWithPath:sourceVideoPathString];
    // 利用源視頻路徑將源視頻轉化為 AVAsset 多媒體載體對象
    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:sourceVideoPathUrl options:nil];
    
    // 源視頻載體對象支持的壓縮格式
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
    // 源視頻載體對象支持的壓縮格式中是否包含我們選擇的壓縮格式
    if ([compatiblePresets containsObject:compressType]) {
        
        // 存放壓縮視頻的文件夾
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *compressVideoFolder = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/compressVideoFolder"];
        if (![fileManager fileExistsAtPath:compressVideoFolder]) {
            
            [fileManager createDirectoryAtPath:compressVideoFolder withIntermediateDirectories:YES attributes:nil error:nil];
        }
        // 用當前系統時間給文件命名, 避免因名字重復而覆蓋存儲
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
        NSString *currentDateString = [formatter stringFromDate:[NSDate date]];
        
        /**
         *  第一個參數 : 要壓縮的 AVAsset 對象
            第二個參數 : 我們選擇的壓縮方式
         */
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:compressType];
        // 壓縮視頻的輸出路徑
        NSString *compressVideoPathString = [compressVideoFolder stringByAppendingPathComponent:[NSString stringWithFormat:@"compressVideo-%@.mp4", currentDateString]];
        NSURL *compressFilePathUrl = [NSURL fileURLWithPath:compressVideoPathString];
        exportSession.outputURL = compressFilePathUrl;
        // 壓縮文件的輸出格式
        exportSession.outputFileType = AVFileTypeMPEG4;
        // 壓縮文件應保證優化網絡使用
        exportSession.shouldOptimizeForNetworkUse = YES;
        // 開始壓縮
        [exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
            
            if (exportSession.status == AVAssetExportSessionStatusCompleted) {
                
                compressSuccessBlock(compressVideoPathString);
            }else {
                
                compressFailedBlock();
            }
        }];
    }else {
        
        compressNotSupportBlock();
    }
}
//刪除壓縮后視頻的方法
+ (void)deleteCompressVideoFromPath:(NSString *)compressVideoPathString {
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *compressVideoFolder = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/compressVideoFolder"];
    if ([fileManager fileExistsAtPath:compressVideoFolder]) {
        
        [fileManager removeItemAtPath:compressVideoFolder error:nil];
    }
}

視頻的base64轉碼,轉碼成功后將返回一堆字符串。

// 編碼
+ (void)base64StringFromString:(NSString *)filePathString
                    SuccessBlock:(SuccessBlock)success
                     FailedBlock:(FailedBlock)failed {
    
    // 獲取文件的二進制數據 data
    NSData *data = [NSData dataWithContentsOfFile:filePathString];
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        // 轉碼 --> 碼文
        NSString *base64String = [data base64EncodedStringWithOptions:0];
        
        if (base64String) {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                success(base64String);
            });
        }else {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                failed();
            });
        }
    });
}

//外部的調用形式
[ZWBase64EncodeTools base64StringFromString:self.filePathString SuccessBlock:^(NSString *string) {
            //轉碼成功后返回一堆字符串
            self.base64StringTextView.text = string;
            self.navigationItem.title = [NSString stringWithFormat:@"壓縮data的Base64碼, %.2fM", string.length / 1024.0 / 1024.0];
        } FailedBlock:^{
            
            self.navigationItem.title = @"轉碼失敗了!";
  }];

說道這里就順便說一下圖片的base64轉碼了。下面方法中fileData是圖片的二進制文件。

+ (void)base64StringFromData:(NSData *)fileData
                      SuccessBlock:(SuccessBlock)success
                   FailedBlock:(FailedBlock)failed {
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        // 轉碼 --> 碼文
        NSString *base64String = [fileData base64EncodedStringWithOptions:0];
        
        if (base64String) {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                success(base64String);
            });
        }else {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                failed();
            });
        }
    });
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容