iPhone:以编程方式压缩录制的视频以进行共享?

Get*_*tsy 42 iphone

在录制视频之前,我在调用摄像机视图时实现了叠加视图.

pickerController.cameraOverlayView =myOverlay;
Run Code Online (Sandbox Code Playgroud)

视频录制并在录制视频和通过电子邮件等共享后将视频保存到相册中一切正常.

如果我将视频质量用作"高品质",那么录制的视频已变得庞大.例如,如果我以高质量录制视频30秒,录制的视频大约为30 - 40 mb.

pickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
Run Code Online (Sandbox Code Playgroud)

如何在共享之前对高质量录制视频进行压缩编程,就像Apple如何使用内置录像机一样?

请指导我解决这个问题.

谢谢!

更新:

这就是我最近的尝试,但仍然没有成功:我想压缩拍摄的录制视频来到didFinishPickingMediaWithInfo并存储在相同的相册实际视频路径本身,而不是其他任何地方.我测试同一个视频被压缩到非常小的尺寸,当我从照片库中选择时,但从相机拍摄的同一视频来自didFinishPickingMediaWithInfo并未压缩,尽管我使用下面的AVAssetExportSession代码.

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

    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];


if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{

    NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
    NSString *urlPath = [videoURL path];

    if ([[urlPath lastPathComponent] isEqualToString:@"capturedvideo.MOV"])
    {
        if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (urlPath))
        {
            [self copyTempVideoToMediaLibrary :urlPath];


        }
        else
        {
            NSLog(@"Video Capture Error: Captured video cannot be saved...didFinishPickingMediaWithInfo()");                
        }
    }       
    else
    {
        NSLog(@"Processing soon to saved photos album...else loop of lastPathComponent..didFinishPickingMediaWithInfo()");
    }
}    
[self dismissModalViewControllerAnimated:YES];
}

- (void)copyTempVideoToMediaLibrary :(NSString *)videoURL {

        dispatch_queue_t mainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(mainQueue, ^{

    ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];

    ALAssetsLibraryWriteVideoCompletionBlock completionBlock = ^(NSURL *assetURL, NSError *error) {
        NSLog(@"Saved URL: %@", assetURL);
        NSLog(@"Error: %@", error);

        if (assetURL != nil) {

            AVURLAsset *theAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:videoURL] options:nil];

            NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:theAsset];

            AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:theAsset presetName:AVAssetExportPresetLowQuality];

            [exportSession setOutputURL:[NSURL URLWithString:videoURL]];
            [exportSession setOutputFileType:AVFileTypeQuickTimeMovie];

            [exportSession exportAsynchronouslyWithCompletionHandler:^ {
                switch ([exportSession status]) {
                    case AVAssetExportSessionStatusFailed:
                        NSLog(@"Export session faied with error: %@", [exportSession error]);
                        break;
                    default:
                        //[self mediaIsReady];
                        break;
                }
            }];
        }
    };

    [library writeVideoAtPathToSavedPhotosAlbum:[NSURL URLWithString:videoURL] completionBlock:completionBlock];
});
}
Run Code Online (Sandbox Code Playgroud)

tid*_*all 67

如果要压缩视频以进行远程共享并保持iPhone上本地存储的原始质量,则应查看AVAssetExportSessionAVAssetWriter.

另请阅读iOS如何管理资产.

- (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:AVAssetExportPresetLowQuality];
    exportSession.outputURL = outputURL;
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;
    [exportSession exportAsynchronouslyWithCompletionHandler:^(void) 
    {
        handler(exportSession);
        [exportSession release];
    }];
}

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

{   
    NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
    NSURL *outputURL = [NSURL fileURLWithPath:@"/Users/josh/Desktop/output.mov"];
    [self convertVideoToLowQuailtyWithInputURL:videoURL outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
     {
         if (exportSession.status == AVAssetExportSessionStatusCompleted)
         {
             printf("completed\n");
         }
         else
         {
             printf("error\n");

         }
     }];

}
Run Code Online (Sandbox Code Playgroud)

  • 嗨,我发现如果我们降低质量,那么实际的高清录制视频(720p)质量会降低,而不是真正的高清视频.我的要求是,如何保持视频具有相同的维度(720p),但在上传(发送)到我的服务器之前减小视频的大小. (2认同)

小智 13

我想这个视频已经被h264编解码器压缩了.但您可以尝试使用AVFoundation从摄像头捕获视频文件.但我怀疑你最终会得到相同的文件大小.

以下是iPhone 4上录制的具有不同质量预设的10秒视频文件的一些统计数据.

high (1280?720) = ~14MB = ~11Mbit/s
640 (640?480) = ~4MB = ~3.2Mbit/s
medium (360?480) = ~1MB = ~820Kbit/s
low (144?192) = ~208KB = ~170Kbit/s
Run Code Online (Sandbox Code Playgroud)

  • 注意:这不适用于较新的iPhone型号,例如iPhone 5,5s等。 (2认同)

Ran*_*all 11

pickerController.videoQuality = UIImagePickerControllerQualityTypeMedium;
Run Code Online (Sandbox Code Playgroud)

这些是您可以选择的所有值.

UIImagePickerControllerQualityTypeHigh    = 0,
UIImagePickerControllerQualityType640x480 = 3,
UIImagePickerControllerQualityTypeMedium  = 1,  // default value
UIImagePickerControllerQualityTypeLow     = 2
Run Code Online (Sandbox Code Playgroud)

  • 不确定是否有其他人有此问题,但当我更改选择器质量(如上所示)时,它不会更改我的文件大小= \ (2认同)

小智 5

使用swift以编程方式压缩视频

并且不要忘记添加 - 导入AssetsLibrary

func convertVideoWithMediumQuality(inputURL : NSURL){

            let VideoFilePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("mergeVideo\(arc4random()%1000)d").URLByAppendingPathExtension("mp4").absoluteString
            if NSFileManager.defaultManager().fileExistsAtPath(VideoFilePath) {
                do {
                    try NSFileManager.defaultManager().removeItemAtPath(VideoFilePath)
                } catch { }
            } 

            let savePathUrl =  NSURL(string: VideoFilePath)!

            let sourceAsset = AVURLAsset(URL: inputURL, options: nil)

            let assetExport: AVAssetExportSession = AVAssetExportSession(asset: sourceAsset, presetName: AVAssetExportPresetMediumQuality)!
            assetExport.outputFileType = AVFileTypeQuickTimeMovie
            assetExport.outputURL = savePathUrl
            assetExport.exportAsynchronouslyWithCompletionHandler { () -> Void in

                switch assetExport.status {
                case AVAssetExportSessionStatus.Completed:
                    dispatch_async(dispatch_get_main_queue(), {
                        do {
                            let videoData = try NSData(contentsOfURL: savePathUrl, options: NSDataReadingOptions())
                            print("MB - \(videoData.length / (1024 * 1024))")
                        } catch {
                            print(error)
                        }

                    })
                case  AVAssetExportSessionStatus.Failed:
                    self.hideActivityIndicator(self.view)
                    print("failed \(assetExport.error)")
                case AVAssetExportSessionStatus.Cancelled:
                    self.hideActivityIndicator(self.view)
                    print("cancelled \(assetExport.error)")
                default:
                    self.hideActivityIndicator(self.view)
                    print("complete")
                }
            }

        }
Run Code Online (Sandbox Code Playgroud)

  • 凉.为什么要使用随机文件名呢?这看起来很可疑.如果您多次调用此函数并希望避免名称冲突,则使用随机文件名并不总是有效并导致问题.如果您一次只调用一个,则不需要随机文件名.我建议使用更确定的命名方案(计数器等) (2认同)