将 CIFilter
与 AVVideoComposition
一起使用时,如何在 AVAsynchronousCIImageFilteringRequest
回调中访问当前帧编号?
我能做的最好的事情就是根据时间估计帧数:
^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {
double seconds = CMTimeGetSeconds(request.compositionTime);
double fps = [[_avAsset tracksWithMediaType:AVMediaTypeVideo] firstObject].nominalFrameRate;
int frame = round(seconds * fps);
// (Calculate filter parameters based on frame number)
}
但这对我来说不够准确。有没有办法获取帧号?
最佳答案
关键是设置 AVMutableVideoComposition
上的 frameDuration
以匹配底层 AVAssetTrack
的帧持续时间。如果这样做,compositionTime
的值将是 minFrameDuration
的偶数倍,并且不会出现任何舍入问题。
AVMutableVideoComposition *vidComp =
[AVMutableVideoComposition videoCompositionWithAsset:self.avAsset
applyingCIFiltersWithHandler:
^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {
CMTime frame = self.avAssetTrack.minFrameDuration;
int frameNum = (request.compositionTime.value * frame.timescale) /
(request.compositionTime.timescale * frame.value);
// (Calculate filter parameters based on frame number)
}];
vidComp.frameDuration = self.avAssetTrack.minFrameDuration;
就我的 ~60 fps MP4 电影而言,avAssetTrack.minFrameDuration = (1001/60000)
,但在我之前 vidComp.frameDuration = (1501/90000)
更新它。这导致回调中“compositionTime”缓慢漂移,从而导致偶尔出现重复帧。
关于avfoundation - 如何访问 AVAsynchronousCIImageFilteringRequest 中的帧号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37754673/