Zakładanie AVSynchonizedLayer

Próbowałem stworzyć proof of concept, który łączy wideo z obiektem animacji (zasadniczo "rotoskopuję" wybraną przez użytkownika bitmapę na puszce wideo w określonych lokalizacjach). Po obejrzeniu wszystkich dostępnych materiałów Apple dotyczących animacji Core (WWDC10 itp.) i AVSync..Layer (przykładowy kod Apple WWDC10, przykładowy kod DOC), po prostu nie ma wystarczająco jasnego izolowanego przykładu kodu, aby dowiedzieć się, jak poprawnie zaimplementować ten tryb odtwarzania.

Używając CA, mam zasób wideo, który jest ładowany do Calayera, i animację, która jest dołączona do bitmapy, a następnie podłączona do innego Calayera. Utworzyłem AVSynchronizedLayer i dodałem oba obiekty jako podwarstwa.

Po dodaniu tego drzewa do Właściwości warstwy UIView spodziewałem się, że odtwarzanie animacji będzie zsynchronizowane z filmem. Zamiast tego widzę tylko odtwarzane wideo, a animacja nigdy nie jest wykonywana - oto odpowiednie fragmenty mojego kodu który znajduje się w jednym kontrolerze widoku (wywoływanym w ViewDidLoad).

Video101.M4V = proste wideo m4v, gerald.png = bitmap

NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"Video101" withExtension:@"m4v"];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];

AVPlayer *player = [[AVPlayer playerWithPlayerItem:playerItem]retain];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = CGRectMake(0, 0, 1024, 768);
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

CALayer *gerald = [CALayer layer];
gerald.frame = CGRectMake(0, 0, 120, 120);
gerald.contents = (id) [UIImage imageNamed:@"gerald.png"].CGImage;

[self.view.layer addSublayer:playerLayer];
[self.view.layer insertSublayer:gerald above:playerLayer];


CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
anim.duration = 18.0;

anim.values = [NSArray arrayWithObjects:
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(310.0, 400.0)],
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(310.0, 400.0)],
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(310.0, 400.0)],
               [NSValue valueWithCGPoint:CGPointMake(480.0, 206.0)],
               [NSValue valueWithCGPoint:CGPointMake(310.0, 400.0)],
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(310.0, 400.0)],
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(10.0, 760.0)],
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(310.0, 400.0)],
               [NSValue valueWithCGPoint:CGPointMake(320.0, 406.0)],
               [NSValue valueWithCGPoint:CGPointMake(310.0, 400.0)], nil];


anim.keyTimes = [NSArray arrayWithObjects:
                 [NSNumber numberWithFloat:0.02],
                 [NSNumber numberWithFloat:0.06],
                 [NSNumber numberWithFloat:0.09],
                 [NSNumber numberWithFloat:0.1], 
                 [NSNumber numberWithFloat:0.12],
                 [NSNumber numberWithFloat:0.2],
                 [NSNumber numberWithFloat:0.25],
                 [NSNumber numberWithFloat:0.32], 
                 [NSNumber numberWithFloat:0.38],
                 [NSNumber numberWithFloat:0.49],
                 [NSNumber numberWithFloat:0.53],
                 [NSNumber numberWithFloat:0.59], 
                 [NSNumber numberWithFloat:0.63],
                 [NSNumber numberWithFloat:0.69],
                 [NSNumber numberWithFloat:0.78],
                 [NSNumber numberWithFloat:0.81], 
                 [NSNumber numberWithFloat:0.91], 
                 [NSNumber numberWithFloat:1.0], nil];


AVSynchronizedLayer *syncLayer = [AVSynchronizedLayer synchronizedLayerWithPlayerItem:playerItem];
[syncLayer addSublayer:gerald];
[gerald addAnimation:anim forKey:@"transform.position"];

[self.view.layer addSublayer:syncLayer];

[player play];

Jaki jest prawidłowy format lub sposób implementacji AVSynchronizedLayer, aby zarówno animacja, jak i wideo były odtwarzane razem?

Author: Hagelin, 2011-05-09

1 answers

Masz CAKeyframeAnimation ustawione poprawnie z wyjątkiem jednego bitu: Zgodnie z wykładem WWDC "Editing Media with AV Foundation", musisz ustawić właściwość beginTime swojej animacji na wartość niezerową.

Zerowy czas rozpoczęcia jest automatycznie tłumaczony na CACurrentMediaTime (). 1E-100 lub-1e-100 (AVCoreAnimationBeginTimeAtZero)

Myślę, że jeśli dodasz anim.beginTime = AVCoreAnimationBeginTimeAtZero; zobaczysz, że animacja zaczyna się zaraz po rozpoczęciu odtwarzania filmu.

 14
Author: Jose Ibanez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-09 21:13:11