這里沒有主要是說下和視頻相關的小技術點,都是一些相對比較基本的,但是對于沒有怎么和視頻打交道的人而言,找一些資料還不是很方便,所以今天就沒事白這些東西給稍微整理了一下。
先看看視頻的錄制,這里主要說的是使用系統的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();
});
}
});
}