這里沒有主要是說下和視頻相關(guān)的小技術(shù)點(diǎn),都是一些相對(duì)比較基本的以躯,但是對(duì)于沒有怎么和視頻打交道的人而言槐秧,找一些資料還不是很方便,所以今天就沒事白這些東西給稍微整理了一下忧设。
先看看視頻的錄制刁标,這里主要說的是使用系統(tǒng)的UIImagePickerController這個(gè)類進(jìn)行視頻的錄制。注意:導(dǎo)入這個(gè)框架才能錄制視頻#import<MobileCoreServices/MobileCoreServices.h>這個(gè)框架后才能播放進(jìn)入系統(tǒng)的錄制視頻界面址晕。
//1膀懈、判斷照相機(jī)是否可用 不可用就直接return 一般都是這樣
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
return;
}
//2.初始化
UIImagePickerController *picker = [UIImagePickerController new];
//3.設(shè)置類型
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//通常4和5是一塊設(shè)置的
//4.設(shè)置媒體類型 默認(rèn)是拍照
picker.mediaTypes = @[(NSString *)kUTTypeMovie];
//注意:如果是UIImagePickerControllerSourceTypePhotoLibrary設(shè)置下面的兩句會(huì)崩潰
//5.設(shè)置攝像機(jī)模式
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo; //6.設(shè)置視頻質(zhì)量
// picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
//7.設(shè)置代理
picker.delegate = self;
//8.模態(tài)彈出
[self presentViewController:picker animated:YES completion:nil];
再看一下錄制的視頻如何保存到本地。注意:保存視頻到本地 需要這個(gè)資源庫<AssetsLibrary/AssetsLibrary.h>
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
//1.判斷是否是視頻的媒體類型
NSString *mediaType = info[UIImagePickerControllerMediaType];
//2.保存視頻到本地 需要這個(gè)資源庫<AssetsLibrary/AssetsLibrary.h>
//必須做這個(gè)判斷
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
//這個(gè)已經(jīng)過期了 iOS9需要換成PHPhotoLibrary
//2.1創(chuàng)建ALAssetsLibrary對(duì)象
ALAssetsLibrary *assetsLibrary = [ALAssetsLibrary new];
//2.2 這個(gè)url是指要保存的視頻的url
[assetsLibrary writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error) {
}];
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
下面是視頻的壓縮的一個(gè)類方法谨垃,以及刪除壓縮后視頻的方法启搂。代碼內(nèi)部有十分詳細(xì)的注釋硼控。說明一下第一個(gè)方法中傳入的sourceVideoPathString是這樣獲取的。在(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info這個(gè)方法中胳赌,通過
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];
// 利用源視頻路徑將源視頻轉(zhuǎn)化為 AVAsset 多媒體載體對(duì)象
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:sourceVideoPathUrl options:nil];
// 源視頻載體對(duì)象支持的壓縮格式
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
// 源視頻載體對(duì)象支持的壓縮格式中是否包含我們選擇的壓縮格式
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];
}
// 用當(dāng)前系統(tǒng)時(shí)間給文件命名, 避免因名字重復(fù)而覆蓋存儲(chǔ)
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
NSString *currentDateString = [formatter stringFromDate:[NSDate date]];
/**
* 第一個(gè)參數(shù) : 要壓縮的 AVAsset 對(duì)象
第二個(gè)參數(shù) : 我們選擇的壓縮方式
*/
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;
// 壓縮文件應(yīng)保證優(yōu)化網(wǎng)絡(luò)使用
exportSession.shouldOptimizeForNetworkUse = YES;
// 開始?jí)嚎s
[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轉(zhuǎn)碼,轉(zhuǎn)碼成功后將返回一堆字符串疑苫。
// 編碼
+ (void)base64StringFromString:(NSString *)filePathString
SuccessBlock:(SuccessBlock)success
FailedBlock:(FailedBlock)failed {
// 獲取文件的二進(jìn)制數(shù)據(jù) data
NSData *data = [NSData dataWithContentsOfFile:filePathString];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 轉(zhuǎn)碼 --> 碼文
NSString *base64String = [data base64EncodedStringWithOptions:0];
if (base64String) {
dispatch_async(dispatch_get_main_queue(), ^{
success(base64String);
});
}else {
dispatch_async(dispatch_get_main_queue(), ^{
failed();
});
}
});
}
//外部的調(diào)用形式
[ZWBase64EncodeTools base64StringFromString:self.filePathString SuccessBlock:^(NSString *string) {
//轉(zhuǎn)碼成功后返回一堆字符串
self.base64StringTextView.text = string;
self.navigationItem.title = [NSString stringWithFormat:@"壓縮data的Base64碼, %.2fM", string.length / 1024.0 / 1024.0];
} FailedBlock:^{
self.navigationItem.title = @"轉(zhuǎn)碼失敗了!";
}];
說道這里就順便說一下圖片的base64轉(zhuǎn)碼了熏版。下面方法中fileData是圖片的二進(jìn)制文件。
+ (void)base64StringFromData:(NSData *)fileData
SuccessBlock:(SuccessBlock)success
FailedBlock:(FailedBlock)failed {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 轉(zhuǎn)碼 --> 碼文
NSString *base64String = [fileData base64EncodedStringWithOptions:0];
if (base64String) {
dispatch_async(dispatch_get_main_queue(), ^{
success(base64String);
});
}else {
dispatch_async(dispatch_get_main_queue(), ^{
failed();
});
}
});
}