Прошло довольно много времени с тех пор, как этот вопрос был задан, но, посмотрев везде, мне удалось придумать нечто похожее, сэмплировав данные в реальном времени во время записи (со скоростью 1/30 с, с таймером для видео, записанного со скоростью 30 кадров в секунду). ) и хранить его в массиве. Затем в постобработке я создаю несколько CALayers в цикле для каждого элемента данных в массиве и рисую визуализацию этих данных на каждом слое.
Каждый слой имеет анимацию CAAnimation, которая исчезает в непрозрачности на правильной временной шкале медиа с атрибутом beginTime , который составляет всего 1/30 сек. умножается на индекс массива. Это настолько короткое время, что слой сразу появляется поверх предыдущего слоя. Если фон слоя непрозрачен, он затеняет иглу, визуализированную в предыдущем слое, и, таким образом, кажется, что анимирует иглу в довольно хорошей синхронизации с оригинальным захватом видео. Возможно, вам придется немного подправить время, но я не более чем на один кадр.
/******** this has not been compiled but you should get the idea ************
// Before starting the AVAssetExportSession session and after the AVMutableComposition routine
CALayer* speedoBackground = [[CALayer alloc] init]; // background layer for needle layers
[speedoBackground setFrame:CGRectMake(x,y,width,height)]; // size and location
[speedoBackground setBackgroundColor:[[UIColor grayColor] CGColor]];
[speedoBackground setOpacity:0.5] // partially see through on video
// loop through the data
for (int index = 0; index < [dataArray count]; index++) {
CALayer* speedoNeedle = [[CALayer alloc] init]; // layer for needle drawing
[speedoNeedle setFrame:CGRectMake(x,y,width,height)]; // size and location
[speedoNeedle setBackgroundColor:[[UIColor redColor] CGColor]];
[speedoNeedle setOpacity:1.0]; // probably not needed
// your needle drawing routine for each data point ... e.g.
[self drawNeedleOnLayer:speedoNeedle angle:[self calculateNeedleAngle[dataArray objectAtIndex:index]]];
CABasicAnimation *needleAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
needleAnimation.fromValue = [NSNumber numberWithFloat:(float)0.0];
needleAnimation.toValue = [NSNumber numberWithFloat:(float)1.0]; // fade in
needleAnimation.additive = NO;
needleAnimation.removedOnCompletion = NO; // it obscures previous layers
needleAnimation.beginTime = index*animationDuration;
needleAnimation.duration = animationDuration -.03; // it will not animate at this speed but layer will appear immediately over the previous layer at the correct media time
needleAnimation.fillMode = kCAFillModeBoth;
[speedoNeedle addAnimation:needleAnimation forKey:nil];
[speedoBackground addSublayer:needleOverlay];
}
[parentLayer addSublayer:speedoBackground];
.
.
.
// when the AVAssetExportSession has finished, make sure you clear all the layers
parentLayer.sublayers = nil;
Он потребляет много ресурсов процессора и памяти, поэтому не подходит для длинных видеороликов или сложных рисунков. Я уверен, что есть более элегантные методы, но это работает, и я надеюсь, что это поможет.