1. 程式人生 > >iOS 錄視訊,相簿選擇視訊,視訊壓縮,儲存本地檔案,播放,上傳

iOS 錄視訊,相簿選擇視訊,視訊壓縮,儲存本地檔案,播放,上傳

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覆蓋更新的時候,路徑會更改。所以我們要重新獲取一下路徑。只能儲存檔案的名字就可以了。