ios – 使用maxRecordedFileSize限制AVCaptureSession记录时间

ios – 使用maxRecordedFileSize限制AVCaptureSession记录时间,第1张

概述我一直在为iOS 8编写一个相机应用程序,它使用AVFoundation来设置和处理录音和保存(不是 ImagePickerController).我试图保存使用AVCaptureMovieFileOutput类的maxRecordedFileSize属性,以允许用户填充手机上的所有可用空间(减去苹果的剩余250MB缓冲区). - (unsigned long long) availableFre 我一直在为iOS 8编写一个相机应用程序,它使用AVFoundation来设置和处理录音和保存(不是 ImagePickerController).我试图保存使用AVCaptureMovIEfileOutput类的maxRecordedfileSize属性,以允许用户填充手机上的所有可用空间(减去苹果的剩余250MB缓冲区).
- (unsigned long long) availableFreespaceInMb {unsigned long long freeSpace;NSError *error = nil;NSArray *paths = NSSearchPathForDirectorIEsInDomains(NSdocumentDirectory,NSUserDomainMask,YES);NSDictionary *dictionary = [[NSfileManager defaultManager] attributesOffileSystemForPath:[paths lastObject] error: &error];if (dictionary) {    NSNumber *fileSystemFreeSizeInBytes = [dictionary objectForKey: NSfileSystemFreeSize];    freeSpace = [fileSystemFreeSizeInBytes unsignedLongLongValue];} else {    NSLog(@"Error getting free space");    //Handle error}//convert to MBfreeSpace = (freeSpace/1024ll)/1024ll;freeSpace -= _recordspaceBufferInMb; // 250 MBNSLog(@"Remaining space in MB: %llu",freeSpace);NSLog(@"    Diff Since Last: %llu",(_prevRemSpaceMb - freeSpace));_prevRemSpaceMb = freeSpace;return freeSpace;

}

当可用空间(减号)减少为零时,抛出AVErrorMaximumfileSizeReached,并且不会抛出保存错误,但视频不会出现在相机胶卷中,并且未保存.当我设置maxRecordedDuration字段时,抛出AVErrorMaximumDurationReached,并保存视频.我从最大大小计算最大时间,但由于帧压缩,我总是留有足够的空间.

- (voID) toggleMovIERecording{double factor = 1.0;if (_currentFramerate == _slowFPS) {    factor = _slowMotionFactor;}double availableRecordTimeInSeconds = [self remainingRecordTimeInSeconds] / factor;unsigned long long remainingSpace = [self availableFreespaceInMb] * 1024 * 1024;if (![[self movIEfileOutput] isRecording]) {    if (availableSpaceInMb < 50) {        NSLog(@"TMR:Not enough space,can't record");        [AVVIEwController currentVIDeoOrIEntation];        [_prevIEwVIEw memoryAlert];        return;    }}if (![self enableRecording]) {    return;}[[self recordbutton] setEnabled:NO];dispatch_async([self sessionQueue],^{    if (![[self movIEfileOutput] isRecording])    {                    if ([[UIDevice currentDevice] isMultitaskingSupported])        {            [self setBackgroundRecordingID:[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]];        }        // Update the orIEntation on the movIE file output vIDeo connection before starting recording.        [[[self movIEfileOutput] connectionWithMediaType:AVMediaTypeVIDeo] setVIDeoOrIEntation: [AVVIEwController currentVIDeoOrIEntation]];//[[(AVCaptureVIDeoPrevIEwLayer *)[[self prevIEwVIEw] layer] connection] vIDeoOrIEntation]];        // Start recording to a temporary file.        Nsstring *outputfilePath = [NstemporaryDirectory() stringByAppendingPathComponent:[@"movIE" stringByAppendingPathExtension:@"mov"]];        // Is there already a file like this?        NSfileManager *fileManager = [NSfileManager defaultManager];        if ([fileManager fileExistsAtPath:outputfilePath]) {            NSLog(@"filexists");            NSError *err;            if ([fileManager removeItemAtPath:outputfilePath error:&err] == NO) {                NSLog(@"Error,file exists at path");            }        }         [_prevIEwVIEw startRecording];        // Set the movIE file output to stop recording a bit before the phone is full        [_movIEfileOutput setMaxRecordedfileSize:remainingSpace]; // Less than the total remaining space       // [_movIEfileOutput setMaxRecordedDuration:CMTimeMake(availableRecordTimeInSeconds,1.0)];        [_movIEfileOutput startRecordingToOutputfileURL:[NSURL fileURLWithPath:outputfilePath] recordingDelegate:self];    }    else    {        [_prevIEwVIEw stopRecording];        [[self movIEfileOutput] stopRecording];    }});}- (voID)captureOutput:(AVCapturefileOutput *)captureOutput dIDFinishRecordingToOutputfileAtURL:(NSURL *)outputfileURL fromConnections:(NSArray *)connections error:(NSError *)errorNSLog(@"AVVIEwController: dIDFinishRecordingToOutputfile");if (error) {    NSLog(@"%@",error);    NSLog(@"Caught Error");    if ([error code] == AVErrordiskFull) {        NSLog(@"Caught disk full error");    } else if ([error code] == AVErrorMaximumfileSizeReached) {        NSLog(@"Caught max file size error");    } else if ([error code] == AVErrorMaximumDurationReached) {        NSLog(@"Caught max duration error");    } else {        NSLog(@"Caught other error");    }    [self remainingRecordTimeInSeconds];    dispatch_async(dispatch_get_main_queue(),^{        [_prevIEwVIEw stopRecording];        [_prevIEwVIEw memoryAlert];    });}// Note the backgroundRecordingID for use in the ALAssetsLibrary completion handler to end the background task associated with this recording. This allows a new recording to be started,associated with a new uibackgroundtaskIDentifIEr,once the movIE file output's -isRecording is back to NO — which happens sometime after this method returns.uibackgroundtaskIDentifIEr backgroundRecordingID = [self backgroundRecordingID];[self setBackgroundRecordingID:uibackgroundtaskInvalID];[[[ALAssetsLibrary alloc] init] writeVIDeoAtPathToSavedPhotosAlbum:outputfileURL completionBlock:^(NSURL *assetURL,NSError *error) {    if (error) {        NSLog(@"%@",error);        NSLog(@"Error during write");    } else {        NSLog(@"Writing to photos album");    }    [[NSfileManager defaultManager] removeItemAtURL:outputfileURL error:nil];    if (backgroundRecordingID != uibackgroundtaskInvalID)        [[UIApplication sharedApplication] endBackgroundTask:backgroundRecordingID];}];if (error) {    [_session stopRunning];    dispatch_after(dispatch_time(disPATCH_TIME_Now,1.0 * NSEC_PER_SEC),_sessionQueue,^{        [_session startRunning];    });}

当两个错误被抛出时,会出现“写入照片相册”.我完全被这个困扰了任何iOS的见解?

解决方法 您提供的代码示例很难测试,因为缺少一个属性和方法.虽然我无法编译你的代码,但肯定会有一些红旗可能导致这个问题.以下问题发现在:
captureOutput:dIDFinishRecordingToOutputfileAtURL:fromConnections:错误:

问题1:该方法正在处理传递的错误,但是继续执行该方法.而应该是:

- (voID)captureOutput:(AVCapturefileOutput *)captureOutput dIDFinishRecordingToOutputfileAtURL:(NSURL *)outputfileURL fromConnections:(NSArray *)connections error:(NSError *)error {     if (error) {        // handle error then bail        return;    }    // continue on}

问题2:您要实例化的ALAssetsLibrary对象不会存储到一个属性中,因此一旦captureOutput:dIDFinishRecordingToOutputfileAtURL:fromConnections:error:finish对象将被释放(可能永远不会触发完成块).相反应该是:

// hold onto the assets library beyond this scopeself.AssetsLibrary = [[ALAssetsLibrary alloc] init];// get weak reference to self for later removal of the assets library__weak typeof(self) weakSelf = self;[self.AssetsLibrary writeVIDeoAtPathToSavedPhotosAlbum:outputfileURL completionBlock:^(NSURL *assetURL,NSError *error) {    // handle error    // handle cleanup    // cleanup new property    weakSelf.AssetsLibrary = nil;}];

如果修复这些问题无法解决问题,请提供缺少的代码,使您的示例编译.

总结

以上是内存溢出为你收集整理的ios – 使用maxRecordedFileSize限制AVCaptureSession记录时间全部内容,希望文章能够帮你解决ios – 使用maxRecordedFileSize限制AVCaptureSession记录时间所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1112405.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存