2011-06-29 17 views
5

Opis aplikacji: Prędkościomierz. Ma igłę i animowaną igłę jako nakładkę na wideo. Generuję animację igły na wideo poprzez przetwarzanie końcowe. Używam AVAssetExportSession i konstruuję AVComposition zawierający moje animowane warstwy wraz ze ścieżkami wideo i audio z wideo. To działa dobrze. Wideo pokazuje, animuje igłę.Jak połączyć/zsynchronizować animację z nagraniem wideo w czasie rzeczywistym?

Obecnie, aby odtworzyć animację podczas przetwarzania końcowego, zaoszczędziłem każdej zmiany prędkości z czasem, od kiedy zaczęło się "nagrywanie" wideo. Podczas postprocessingu odpalam timer (y) w oparciu o zapisane dane czasu/prędkości, aby następnie animować igłę do następnej prędkości.

Problem: Wynikające wideo/para animacja nie są w pełni dokładne i tam często jest niedopasowanie pomiędzy prędkością wskazywaną gdy film został usunięty, a gdy jest odtwarzany i komponowane. (zwykle igła jest przed wideo) ze względu na fakt, że kompozycja/kompresja podczas eksportu niekoniecznie jest w czasie rzeczywistym.

Pytanie: Czy istnieje sposób mogę umieścić informacje o prędkości do strumienia wideo nagrywania, a następnie uzyskać do niego dostęp, gdy jest eksportowane tak, że film i prędkościomierz są czasowo dopasowane?

Byłoby miło uzyskać wywołanie zwrotne w określonych godzinach podczas eksportu, który zawiera moje dane dotyczące prędkości.

Jak zawsze ... dzięki!

Odpowiedz

1

Zamiast używać timerów do animacji igły, utwórz animację klatki kluczowej na podstawie zarejestrowanych danych prędkości.

Timery i CA zazwyczaj nie mieszają się dobrze, przynajmniej nie w sposób, który wynika z twojego opisu.

1

Jeśli chcesz osadzić metadane, gdy aplikacja działa na iPhonie, nie wiem, jak to zrobić. Jeśli możesz zrobić osadzanie przed, użyj HTTP LIve Streaming i narzędzia HTTP Live Streaming Tools.

Metadane są generowane w pliku przez id3taggenerator i osadzane na wideo przy użyciu mediafilesegmenter. Przykład:

id3taggenerator -o camera1.id3 -text "Dolly camera" 
id3taggenerator -o camera2.id3 -text "Tracking camera" 

Istnieje kilka rodzajów metadanych, które można osadzać, w tym obiekty binarne. Szczegółowe informacje znajdują się na stronie podręcznika. Teraz musimy odwołać się do wygenerowanego pliku z "pliku makra meta". Jest to zwykły plik tekstowy z następującym formacie:

60 id3 camera1.id3 
120 id3 camera2.id3 

Pierwszy numer jest sekund, które upłynęły od początku filmu, w którym chcesz wstawić powiadomienie. Nie pamiętam dokładnie polecenia mediafilesegmenter, przepraszam, musisz przynajmniej przekazać plik makra, indeks i plik wideo.

Wynikowy film wideo zawiera metadane publikowane przez jako powiadomienia. Zobacz tę stronę, aby uzyskać szczegółowe informacje: http://jmacmullin.wordpress.com/2010/11/03/adding-meta-data-to-video-in-ios/

0

Istnieje sesja z tegorocznego WWDC, która może zapewnić inne podejście do tego, co robisz. Tutaj możesz obejrzeć filmy: http://developer.apple.com/videos/wwdc/2011/. Poszukaj zwanej "Praca z mediami w AVFoundation". Interesujące kawałki są około minuty 26 lub mniej. Nie jestem całkowicie pewien, że rozumiem problem, ale kiedy go przeczytałem, ta sesja przyszła mi do głowy.

Pozdrawiamy.

1

Powinieneś używać CAAnimations i właściwości beginTime do ustawiania animacji z wyprzedzeniem, a następnie użyć AVVideoComposition + AVVideoCompositionCoreAnimationTool, aby dodać je do wideo podczas eksportowania. Uwaga swoje stany dokumentacja:

Wszelkie animacje będą interpretowane na osi czasu pliku wideo, a nie w czasie rzeczywistym ...

więc animacje będą wyrównane, gdzie dokładnie określić z powstałego filmu.

1

Minęło trochę czasu, odkąd zadawano to pytanie, ale po obejrzeniu wszystkiego, udało mi się wymyślić coś podobnego, próbkując dane w czasie rzeczywistym podczas nagrywania (o 1/30 sek. Z zegarem dla filmu zarejestrowanego pod adresem 30 fps) i przechowywanie go w tablicy. Następnie w przetwarzaniu końcowym tworzę wiele CALayerów w pętlę dla każdego elementu danych w tablicy i rysuję wizualizację tych danych na każdej warstwie.

Każda warstwa ma CAAnimation, która zanika w nieprzezroczystości na prawidłowej osi czasu nośnika z atrybutem atrybutu beginTime, który wynosi zaledwie 1/30 sekundy. pomnożone przez indeks tablicy. Jest to tak krótki czas, że warstwa natychmiast pojawia się na poprzedniej warstwie. Jeśli tło warstwy jest nieprzezroczyste, zasłoni ona igłę renderowaną w poprzedniej warstwie i wydaje się animować igłę w dość dobrej synchronizacji z oryginalnym przechwytywaniem wideo. Być może będziesz musiał nieco zmienić czas, ale nie mam więcej niż jedną klatkę.

/******** 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; 

Jest to procesor i intensywna pamięć, więc nie nadaje się do długich filmów lub złożonego rysunku. Jestem pewien, że istnieją bardziej eleganckie metody, ale to działa i mam nadzieję, że to pomoże.

+0

W jaki sposób dodajemy animację lub efekt przejścia do wideo, stworzyliśmy wideo z obrazów, czy moglibyście wiedzieć, w jaki sposób dodajemy efekt. Użyliśmy https://github.com/caferrara/img-to-video do stworzenia obrazu wideo. –

Powiązane problemy