視頻的錄制、保存、壓縮以及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();
            });
        }
    });
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容