将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)
}
但这对我来说不够准确。有没有办法访问帧号?
答案 0 :(得分:3)
关键是要设置secondary_marker
上的frameDuration
以匹配基础AVMutableVideoComposition
的{{1}}。如果你这样做,那么AVAssetTrack
的值将是compositionTime
的倍数,并且不会有任何舍入问题。
minFrameDuration
在我的大约60 fps MP4电影的情况下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;
,但在我更新之前avAssetTrack.minFrameDuration = (1001/60000)
。这导致回调中'compositionTime'缓慢漂移,导致偶尔出现重复帧。
答案 1 :(得分:0)
如何(一个hacky)
__block int frameNum = 0;
AVMutableVideoComposition *vidComp =
[AVMutableVideoComposition videoCompositionWithAsset:self.avAsset
applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * request) {
// (Calculate filter parameters based on frame number)
frameNum++;
}];
这里有两个假设:
我不知道这些是否是安全的假设。
P.S。帧速率通常是可变的,因此最小值,最大值和帧持续时间可能会产生误导。
更新问题中的AVComposition
用于AVPlayer
中可查询的播放,违反假设1.