你如何访问 AVAsynchronousCIImageFilteringRequest 中的帧号?
How do you access the frame number inside AVAsynchronousCIImageFilteringRequest?
将 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
的 frameDuration
。如果你这样做,那么 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' 的缓慢漂移,导致偶尔出现重复帧。
怎么样(一个hacky)
__block int frameNum = 0;
AVMutableVideoComposition *vidComp =
[AVMutableVideoComposition videoCompositionWithAsset:self.avAsset
applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * request) {
// (Calculate filter parameters based on frame number)
frameNum++;
}];
?
这里有两个假设:
- 您的处理程序的调用顺序与帧的顺序相同
- 您的处理程序一次未被多个线程调用
我不知道这些假设是否安全。
p.s。帧速率经常变化,因此最小值、最大值和帧持续时间可能会产生误导。
UPDATE 问题中的 AVComposition
用于在违反假设 1 的 AVPlayer
中进行可搜索播放。
将 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
的 frameDuration
。如果你这样做,那么 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' 的缓慢漂移,导致偶尔出现重复帧。
怎么样(一个hacky)
__block int frameNum = 0;
AVMutableVideoComposition *vidComp =
[AVMutableVideoComposition videoCompositionWithAsset:self.avAsset
applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * request) {
// (Calculate filter parameters based on frame number)
frameNum++;
}];
?
这里有两个假设:
- 您的处理程序的调用顺序与帧的顺序相同
- 您的处理程序一次未被多个线程调用
我不知道这些假设是否安全。
p.s。帧速率经常变化,因此最小值、最大值和帧持续时间可能会产生误导。
UPDATE 问题中的 AVComposition
用于在违反假设 1 的 AVPlayer
中进行可搜索播放。