Ios 如何使用AVCaptureDeviceFormat从iPhone录制timelapse视频?
我正在尝试通过iphone录制timelapse视频。我已经让它为慢动作工作了(通过捕捉尽可能多的帧),每秒120帧 现在,我尝试反转逻辑以捕获尽可能少的帧,以实现timelapse功能 代码流如下所示:Ios 如何使用AVCaptureDeviceFormat从iPhone录制timelapse视频?,ios,iphone,avcapturesession,avcapturemoviefileoutput,Ios,Iphone,Avcapturesession,Avcapturemoviefileoutput,我正在尝试通过iphone录制timelapse视频。我已经让它为慢动作工作了(通过捕捉尽可能多的帧),每秒120帧 现在,我尝试反转逻辑以捕获尽可能少的帧,以实现timelapse功能 代码流如下所示: 从AVCaptureDevice的可用设备格式中查询所有支持的帧范围 检查帧速率是否低于或等于所需的20 fps,尺寸是否等于或大于1920*1080 除了按下record键时出现“AVCaptureMovieFileOutput-无活动/启用的连接”异常外,所有操作都正常。我只使用提供的帧速
#define kTimelapseRequiredFPS = 20
#define kMinRequiredDimensions (1920*1080)
- (void)configureCameraForSlowMoRecording:(AVCaptureDevice *)currentCaptureDevice
{
[_captureSession beginConfiguration];
AVCaptureDeviceFormat *bestFormat = nil;
AVFrameRateRange *bestFrameRateRange = nil;
for ( AVCaptureDeviceFormat *format in [currentCaptureDevice formats] )
{
//NSLog(@"Format: %@", format);
CMFormatDescriptionRef videoInfo = [format formatDescription];
double videoWidth = CMVideoFormatDescriptionGetDimensions(videoInfo).width;
double videoHeight = CMVideoFormatDescriptionGetDimensions(videoInfo).height;
double dimensions = videoWidth * videoHeight;
for ( AVFrameRateRange *range in format.videoSupportedFrameRateRanges )
{
//NSLog(@"Range: %@", range);
if ((range.maxFrameRate <= kTimelapseRequiredFPS) && (dimensions >= kMinRequiredDimensions))
{
bestFormat = format;
bestFrameRateRange = range;
}
}
}
if ( bestFormat )
{
NSLog(@"Final format: %@, Final range %@", bestFormat, bestFrameRateRange);
if ( [currentCaptureDevice lockForConfiguration:NULL] == YES )
{
currentCaptureDevice.activeFormat = bestFormat;
currentCaptureDevice.activeVideoMinFrameDuration = bestFrameRateRange.minFrameDuration;
currentCaptureDevice.activeVideoMaxFrameDuration = bestFrameRateRange.minFrameDuration;
[currentCaptureDevice unlockForConfiguration];
}
}
[_captureSession commitConfiguration];
}
#定义ktimeReleaseRequiredFPS=20
#定义KMINR要求的尺寸(1920*1080)
-(无效)配置CameraforFlowMoreRecording:(AVCaptureDevice*)currentCaptureDevice
{
[[捕获会话开始配置];
AVCaptureDeviceFormat*bestFormat=nil;
AVFrameRateRange*bestFrameRateRange=nil;
用于(在[currentCaptureDevice formats]中的AVCaptureDeviceFormat*格式)
{
//NSLog(@“格式:%@”,格式);
CMFormatDescriptionRef videoInfo=[format formatDescription];
双videoWidth=CMVideoFormatDescriptionGetDimensions(videoInfo).width;
双视频高度=CMVideoFormatDescriptionGetDimensions(videoInfo).height;
双尺寸=视频宽度*视频高度;
用于(格式为AVFrameRateRange*范围。videoSupportedFrameRateRanges)
{
//NSLog(@“范围:%@”,范围);
如果((range.maxFrameRate=kMinRequiredDimensions))
{
最佳格式=格式;
bestFrameRateRange=范围;
}
}
}
if(最佳格式)
{
NSLog(@“最终格式:%@,最终范围%@”,最佳格式,最佳帧率范围);
如果([currentCaptureDevice lockForConfiguration:NULL]==是)
{
currentCaptureDevice.activeFormat=bestFormat;
currentCaptureDevice.activeVideoMinFrameDuration=bestFrameRateRange.minFrameDuration;
currentCaptureDevice.activeVideoMaxFrameDuration=bestFrameRateRange.minFrameDuration;
[currentCaptureDevice unlockForConfiguration];
}
}
[_CaptureSessionCommitteConfiguration];
}
以下是20 fps的帧速率和范围日志:
Format: <AVCaptureDeviceFormat: 0x1765f7a0 'vide'/'420v' 2592x1936, { 1- 20 fps}, fov:56.700, max zoom:153.00 (upscales @1.26), AF System:1, ISO:46.0-736.0, SS:0.000018-1.000000>
Range: <AVFrameRateRange: 0x176556d0 1 - 20>
Format: <AVCaptureDeviceFormat: 0x1765f750 'vide'/'420f' 2592x1936, { 1- 20 fps}, fov:56.700, max zoom:153.00 (upscales @1.26), AF System:1, ISO:46.0-736.0, SS:0.000018-1.000000>
Range: <AVFrameRateRange: 0x1750db10 1 - 20>
Format: <AVCaptureDeviceFormat: 0x1765f740 'vide'/'420v' 3264x2448, { 1- 20 fps}, fov:56.700, max zoom:153.00 (upscales @1.00), AF System:1, ISO:46.0-736.0, SS:0.000018-1.000000>
Range: <AVFrameRateRange: 0x1750dc80 1 - 20>
Format: <AVCaptureDeviceFormat: 0x1765f6f0 'vide'/'420f' 3264x2448, { 1- 20 fps}, fov:56.700, max zoom:153.00 (upscales @1.00), AF System:1, ISO:46.0-736.0, SS:0.000018-1.000000>
Range: <AVFrameRateRange: 0x1751a260 1 - 20>
格式:
范围:
格式:
范围:
格式:
范围:
格式:
范围:
不确定这个问题是否得到解决,但我一直在努力以慢动作工作,并不断得到“AVCaptureMovieFileOutput-无活动/启用的连接”
(因此我真的很想知道如何让它工作:D)。但不管怎么说,我解决了这个问题,这里有一些棘手的东西,我认为也可以解决你的问题:
activeFormat
之前,请确保设置了一些预设。事实证明,iOS不会自动处理其他东西。我所做的是在设置
activeFormat
转换为每秒120帧的格式Error-Domain=AVFoundationErrorDomain-code=-11803“无法录制”UserInfo=0x152e60{nsLocalizedRecoverysSuggestion=再次尝试录制,AVErrorRecordingSuccessfullyFinishedKey=false,NSLocalizedDescription=无法录制}
。我找不到任何可能的原因-连接正常,会话正在运行。所以我再次按下录制按钮,它开始录制(哇,真的吗?只是字面上的“再试一次”?)我想iOS只是有点脾气,需要考虑更长的时间才能录制。因此,我添加了一个递归函数,以给movieFileOutput
一些记录时间。(对不起,是Swift)
希望它能有所帮助(或者像我一样偶然发现这条线索的其他人)。不确定这是否解决了,但我一直在缓慢地工作,并且不断地得到
“AVCaptureMovieFileOutput-没有活动/启用的连接”
(所以我真的很想知道如何让它工作:D)。但不管怎么说,我解决了这个问题,这里有一些棘手的东西,我认为也可以解决你的问题:
activeFormat
之前,请确保设置了一些预设。事实证明,iOS不会自动处理其他东西。我所做的是在设置
activeFormat
转换为每秒120帧的格式Error-Domain=AVFoundationErrorDomain-code=-11803“无法录制”UserInfo=0x152e60{nsLocalizedRecoverysSuggestion=再次尝试录制,AVErrorRecordingSuccessfullyFinishedKey=false,NSLocalizedDescription=无法录制}
。我找不到任何可能的原因-连接正常,会话正在运行。所以我再次按下录制按钮,它开始录制(哇,真的吗?只是字面上的“再试一次”?)我想iOS只是有点脾气,需要考虑更长的时间才能录制。因此,我添加了一个递归函数,以给movieFileOutput
一些记录时间。(对不起,是Swift)
fileprivate func startRecording(to moviePath: URL) {
sessionQueue.async {
self.movieFileOutput.startRecording(to: moviePath, recordingDelegate: self)
if self.movieFileOutput.isRecording {
self.sessionQueue.asyncAfter(deadline: .now() + self.duration) {
self.stopRecording()
}
} else {
self.startRecording(to: moviePath)
}
}
}