iOS 錄視訊,相簿選擇視訊,視訊壓縮,儲存本地檔案,播放,上傳
阿新 • • 發佈:2019-01-08
iOS 錄視訊,相簿選擇視訊,視訊壓縮,儲存本地檔案,播放,上傳
工程中用到了這部分的功能,也糾結了幾天後做完了,現在總結下這部分的東西。
先說描述下需求:
(1)從相簿取視訊、錄視訊;
(2)視訊轉碼為mp4;
(3)儲存在檔案中,覆蓋更新後也能讀取視訊
(4)視訊的播放
注意:在iOS9之後需要在plist檔案中新增一些限制
Privacy - Microphone Usage Description App需要您的同意,才能訪問麥克風
Privacy - Photo Library Usage Description “App需要您的同意,才能訪問相簿”
Privacy - Camera Usage Description “App需要您的同意,才能訪問相機”
Privacy - Media Library Usage Description “App需要您的同意,才能訪問媒體資源庫”
匯入的庫檔案
#import <MobileCoreServices/MobileCoreServices.h>
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <MediaPlayer/MediaPlayer.h>
使用的UIImagePickerController <UIImagePickerControllerDelegate,UINavigationControllerDelegate>
一、讀取本地的視訊,並播放
注意:新增本地視訊的方法:
讀取地址:
NSString *str = [[NSBundle mainBundle] resourcePath];
NSString *filePath = [NSString stringWithFormat:@“%@%@",str,@"/123.mp4"];
NSURL *sourceMovieURL = [NSURL fileURLWithPath:filePath];
- (void)playVideowithUrl:(NSURL *)url{
AVAsset *movieAsset = [AVURLAsset URLAssetWithURL:url options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:movieAsset];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = CGRectMake(0, 230,300, 150);
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[self.view.layer addSublayer:playerLayer];
playerLayer.backgroundColor = [UIColor blueColor].CGColor;
[player play];
}
二、呼叫相機,相簿獲取視訊
//點選視訊錄製的按鈕
- (IBAction)videoButtonClick:(UIButton *)sender {
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"視訊" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction * firstAction = [UIAlertAction actionWithTitle:@"從相簿獲取視訊" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self choosevideo];
}];
UIAlertAction * secondAction = [UIAlertAction actionWithTitle:@"錄製視訊" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self openLocalCamera];
}];
[alert addAction:firstAction];
[alert addAction:secondAction];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)choosevideo
{
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//sourcetype有三種分別是camera,photoLibrary和photoAlbum
NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera所支援的Media格式都有哪些,共有兩個分別是@"public.image",@"public.movie"
ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];//設定媒體型別為public.movie
[self presentViewController:ipc animated:YES completion:nil];
ipc.delegate = self;//設定委託
}
- (void)openLocalCamera{
UIImagePickerController * picker = [[UIImagePickerController alloc]init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//錄製視訊時長,預設10s
picker.videoMaximumDuration = 20;
//相機型別(拍照、錄影...)這裡表示我們開啟相機支援的是相機和錄影兩個功能。
picker.mediaTypes = @[(NSString *)kUTTypeMovie];
picker.delegate = self;
picker.videoQuality = UIImagePickerControllerQualityTypeHigh;
//設定攝像頭模式(拍照,錄製視訊)為相機模式
// UIImagePickerControllerCameraCaptureModeVideo 這個是設定為視訊模式
picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
[self presentViewController:picker animated:YES completion:nil];
}
#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//如果是視訊資源
NSURL *sourceURL = info[UIImagePickerControllerMediaURL];
NSLog(@"%@",[NSString stringWithFormat:@"%f s", [self getVideoLength:sourceURL]]);
NSLog(@"%@", [NSString stringWithFormat:@"%.2f kb", [self getFileSize:[sourceURL path]]]);
self.videoImage.image = [self thumbnailImageForVideo:sourceURL atTime:1];
self.videoUrl = sourceURL;
NSURL *newVideoUrl ; //一般.mp4
[picker dismissViewControllerAnimated:YES completion:^{}];
[self compressedVideoOtherMethodWithURL:sourceURL compressionType:@"AVAssetExportPresetMediumQuality"];
}
- (void)compressedVideoOtherMethodWithURL:(NSURL *)url compressionType:(NSString *)compressionType {
NSString *resultPath;
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
// 所支援的壓縮格式中是否有 所選的壓縮格式
if ([compatiblePresets containsObject:compressionType]) {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:compressionType];
NSDateFormatter *formater = [[NSDateFormatter alloc] init];// 用時間, 給檔案重新命名, 防止視訊儲存覆蓋,
[formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
NSFileManager *manager = [NSFileManager defaultManager];
BOOL isExists = [manager fileExistsAtPath:CompressionVideoPaht];
if (!isExists) {
[manager createDirectoryAtPath:CompressionVideoPaht withIntermediateDirectories:YES attributes:nil error:nil];
}
NSInteger num = random()%1000;
resultPath = [CompressionVideoPaht stringByAppendingPathComponent:[NSString stringWithFormat:@"outputJFVideo-%@.mov",[NSNumber numberWithInteger:num]]];
[useDefault setValue:[NSNumber numberWithInteger:num] forKey:@"videoRandom"];
[useDefault synchronize];
NSLog(@"resultPath = %@",resultPath);
exportSession.outputURL = [NSURL fileURLWithPath:resultPath];
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession.shouldOptimizeForNetworkUse = YES;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSData *data = [NSData dataWithContentsOfFile:resultPath];
float memorySize = (float)data.length / 1024 / 1024;
NSLog(@"視訊壓縮後大小 %f", memorySize);
self.fileVideoImage.image = [self thumbnailImageForVideo:[NSURL fileURLWithPath:resultPath] atTime:1];
[self playVideowithUrl:[NSURL fileURLWithPath:resultPath]];
} else {
NSLog(@"壓縮失敗");
}
}];
} else {
NSLog(@"不支援 %@ 格式的壓縮", compressionType);
}
}
注意播放壓縮後匯出會有一個檔案的儲存地址。如果我們用到了資料庫,會在資料庫中的一個欄位下儲存這個檔案的路徑,這樣就會有一個檔案的路徑,但是不能儲存絕對路徑。因為在app覆蓋更新的時候,路徑會更改。所以我們要重新獲取一下路徑。只能儲存檔案的名字就可以了。