我注意到我的应用发生了一件奇怪的事情。这是一个使用 AVFoundation 类的视频应用程序。
我需要在给定的时间触发一些事件。我放了一些代码然后我评论它:
/* I prepare the movie clip */
AVMutableComposition *composition = [[AVMutableComposition alloc] init];
NSBundle *bundle = [NSBundle mainBundle];
NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
NSString *path = [bundle pathForResource:@"13.VIDEO_A (BAULE)" ofType:@"mp4"];
NSURL *videoUrl = [NSURL fileURLWithPath:path];
AVURLAsset* sourceAsset = [AVURLAsset URLAssetWithURL:videoUrl options:optionsDictionary];
[composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, [sourceAsset duration]) ofAsset:sourceAsset atTime:currentTime error:NULL];
在我的 viewDidLoad 中,我准备了剪辑。我使用 AVUrlAsset 能够将选项字典与 AVURLAssetPreferPreciseDurationAndTimingKey 一起使用以进行更精确的使用。
/* I create the player */
AVPlayer *mPlayer = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithAsset:composition]];
AVPlayerLayer *mPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:mPlayer];
mPlayerLayer.frame = CGRectMake(0.00, 96.00, 1024.00, 576.00);
[self.view.layer addSublayer: mPlayerLayer];
我用我的 AVUrlasset 中的项目创建一个播放器,然后在我的视图中创建一个布局
/* I set the observer */
[mPlayer addPeriodicTimeObserverForInterval:CMTimeMake(5,25) queue:NULL usingBlock:^(CMTime time) {
NSLog(@"Event : value: %lld, timescale %d, seconds: %f",
time.value, time.timescale,(float) time.value / time.timescale); }];
我设置观察者,每 5/25 秒,0,2 秒(25 是电影的帧速率)。在我的块中,我现在只写日志。
/* Play the movie */
[mPlayer play];
最后我玩。
似乎一切正常,除了我的日志是错误的:
2012-11-15 16:43:05.382 PerfectCircle Beta[6680:707] Evento : value: 0, timescale 1, seconds: 0.000000
2012-11-15 16:43:05.410 PerfectCircle Beta[6680:707] Evento : value: 0, timescale 1, seconds: 0.000000
2012-11-15 16:43:05.563 PerfectCircle Beta[6680:707] Evento : value: 0, timescale 1, seconds: 0.000000
2012-11-15 16:43:05.580 PerfectCircle Beta[6680:707] Evento : value: 0, timescale 1, seconds: 0.000000
2012-11-15 16:43:05.747 PerfectCircle Beta[6680:707] Evento : value: 5489807, timescale 1000000000, seconds: 0.005490
2012-11-15 16:43:05.751 PerfectCircle Beta[6680:707] Evento : value: 8949705, timescale 1000000000, seconds: 0.008950
2012-11-15 16:43:05.753 PerfectCircle Beta[6680:707] Evento : value: 10679967, timescale 1000000000, seconds: 0.010680
2012-11-15 16:43:05.990 PerfectCircle Beta[6680:707] Evento : value: 248121672, timescale 1000000000, seconds: 0.248122
2012-11-15 16:43:06.169 PerfectCircle Beta[6680:707] Evento : value: 426865945, timescale 1000000000, seconds: 0.426866
在随机数量的火灾之后,它的开始计数很好。但它在开始时触发事件的次数增加了 5/6 倍。我尝试了不同的电影和编解码器。如果我提高费率(es: CMTimeMake(25,25) )没有任何改变。
addBoundaryTimeObserverForTimes
我以这种方式开始我的工作:
NSArray *starts = [NSArray arrayWithObjects:[NSValue valueWithCMTime:CMTimeMakeWithSeconds(0.2,25)],nil];
[_player addBoundaryTimeObserverForTimes:starts queue:NULL usingBlock:^{ log_function }];
但我有同样的问题。但是在这里,如果我提高利率,我就不会再看到问题了(但这对我的目标不利)。我的问题是我必须精确计算电影在一个精确时刻播放了多少次。而且我无法对其进行测试,if (currenttime==0.3)
因为它不精确。
这是一个错误?我想念什么?你听说过类似的事情吗?
感谢您的帮助。丹尼尔
更新:在开始和结束时似乎是一个问题。
2012-11-15 16:43:05.747 PerfectCircle Beta[6680:707] Evento : value: 0, timescale 1, seconds: 0.000000
2012-11-15 16:43:05.747 PerfectCircle Beta[6680:707] Evento : value: 5489807, timescale 1000000000, seconds: 0.005490
错误的日志与正确的日志有不同的时间尺度。在播放结束时也会发生同样的情况。似乎在开始和结束时它会执行计时器,但电影尚未加载或已经关闭。我尝试在比赛后放置观察者,但没有任何改变。
我还为我的 CMTimeMake 尝试了不同且更高的时间尺度......但没有效果