簡體   English   中英

以Mp4格式捕獲視頻

[英]Capture Video in Mp4 format

我正在使用UIImagePickerController錄制視頻,問題是它以mov格式錄制視頻以實現android兼容性。

我需要使用以下代碼將視頻轉換為mp4格式,問題是它花費了6秒鍾的時間,大約需要30到35秒。 我可以直接以mp​​4格式或更快的方法錄制視頻的任何解決方案都會有很大幫助。 提前致謝

   -(void)movToMp4:(NSURL *)videoURL{ // method for mov to mp4 conversion

    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
    if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
    {
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString* videoPath = [NSString stringWithFormat:@"%@/xyz.mp4", [paths objectAtIndex:0]];
        exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
        exportSession.outputFileType = AVFileTypeMPEG4;
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            switch ([exportSession status]) {  // switch case to get completion case where i put my delegate
                    return;
                    break;
                case AVAssetExportSessionStatusCompleted: {
                     [self.delegate mp4Response:videoPath];
                        break;

                    }

                }

            }
        }];
    }

}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    NSLog(@"file info = %@", info);
    NSString *pickedType = [info objectForKey:@"UIImagePickerControllerMediaType"];
   NSData *videoData;
    if ([pickedType isEqualToString:@"public.movie"]){

        NSURL *videoUrl=(NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];
        videoData = [NSData dataWithContentsOfURL:videoUrl];

    }

    [self dismissViewControllerAnimated:YES completion:^{

        // 
        [self writeFileData:videoData];
    }];

}

// to get path of document directory
- (NSString *)applicationDocumentsDirectory
{
    //    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return documentsDirectory;
}

- (void) writeFileData:(NSData *)fileData{



    float size = fileData.length / (1024 * 1024);

    NSString *fileName = nil;
    NSString *strPath =  nil;

    NSString *documentsDirectory = [self applicationDocumentsDirectory];

    double CurrentTime = CACurrentMediaTime();


        fileName = [NSString stringWithFormat:@"%d.mp4",(int)CurrentTime];


    strPath =  [documentsDirectory stringByAppendingPathComponent:fileName];
    NSFileManager *filemanager=[[NSFileManager alloc] init];
    NSError *er;

    if (![filemanager fileExistsAtPath:documentsDirectory]) {
        [filemanager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:&er];
        NSLog(@"error in folder creation = %@", er);

    }

    NSLog(@"size of data = %lu", (unsigned long)[fileData length]);
    BOOL saved = [fileData writeToFile:strPath atomically:YES];
    if (saved) {
        NSURL *videoURL = [NSURL URLWithString:strPath];
        // now u can handle mp4 video from videoURL
        }
    else
        return;


}

是的,因為使用AVURLAsset從庫/專輯中加載視頻會花費一些時間。

因此,您需要在此處使用block來從庫中加載視頻。

還行

[self.delegate mp4Response:videoPath];

哪個在完成塊中-應該在主線程上。

請遵循以下方法:

UIImagePickerController委托方法從庫中獲取視頻。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSURL *localUrl = (NSURL *)[info valueForKey:UIImagePickerControllerMediaURL];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* videoPath = [NSString stringWithFormat:@"%@/xyz.mp4", [paths objectAtIndex:0]];
    NSURL *outputURL = [NSURL fileURLWithPath:videoPath];

    [self convertVideoToLowQuailtyWithInputURL:localUrl outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
     {
         if (exportSession.status == AVAssetExportSessionStatusCompleted) {
             NSLog(@"Capture video complete");
             [self performSelectorOnMainThread:@selector(doneCompressing) withObject:nil waitUntilDone:YES];
         }
     }];
    [self dismissViewControllerAnimated:YES completion:nil];
}


- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL handler:(void (^)(AVAssetExportSession*))handler {
    [[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetPassthrough];
    exportSession.outputURL = outputURL;
    exportSession.outputFileType = AVFileTypeMPEG4;
    [exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
         handler(exportSession);
     }];
}

didFinishPickingMediaWithInfo方法中觀察到以下行:

[self performSelectorOnMainThread:@selector(doneCompressing) withObject:nil waitUntilDone:YES];

它將在主線程中(在前台)調用另一種方法doneCompressing 這樣您就可以在doneCompressing調用委托方法。 這將減少時間。

- (void) doneCompressing {
      [self.delegate mp4Response:videoPath];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM