Zrobiłem odtwarzacz wideo, który analizuje ścieżki audio i wideo w czasie rzeczywistym z aktualnie odtwarzanego wideo. Filmy wideo są przechowywane na urządzeniu z systemem iOS (w katalogu Dokumenty aplikacji).iOS: dotknij audio i wideo z Airplay
To wszystko działa dobrze. Używam MTAudioProcessingTap, aby uzyskać wszystkie próbki audio i zrobić FFT, i analizuję wideo, kopiując bufory pikseli z aktualnie odtwarzanego CMTime (właściwość currentTime AVPlayer). Jak już powiedziałem, to działa dobrze.
Ale teraz chcę wesprzeć Airplay. Sam utwór nie jest trudny, ale moje krany przestają działać, gdy tylko Airplay jest przełączany, a wideo jest odtwarzane na ATV. Jakoś, MTAudioProcessingTap nie przetworzy się, a bufory pikselowe będą puste ... Nie mogę dostać się do danych.
Czy można uzyskać dostęp do tych danych?
Aby uzyskać bufory pikselowe, po prostu uruchamiam wydarzenie co kilka milisekund i odbieram currentTime gracza. Następnie:
CVPixelBufferRef imageBuffer = [videoOutput copyPixelBufferForItemTime:time itemTimeForDisplay:nil];
CVPixelBufferLockBaseAddress(imageBuffer,0);
uint8_t *tempAddress = (uint8_t *) CVPixelBufferGetBaseAddress(imageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
Gdzie jest moja pixelbuffer tempAddress
i videoOutput
jest instancją AVPlayerItemVideoOutput
.
audio, używam:
AVMutableAudioMixInputParameters *inputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:audioTrack];
// Create a processing tap for the input parameters
MTAudioProcessingTapCallbacks callbacks;
callbacks.version = kMTAudioProcessingTapCallbacksVersion_0;
callbacks.clientInfo = (__bridge void *)(self);
callbacks.init = init;
callbacks.prepare = prepare;
callbacks.process = process;
callbacks.unprepare = unprepare;
callbacks.finalize = finalize;
MTAudioProcessingTapRef tap;
OSStatus err = MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks,
kMTAudioProcessingTapCreationFlag_PostEffects, &tap);
if (err || !tap) {
NSLog(@"Unable to create the Audio Processing Tap");
return;
}
inputParams.audioTapProcessor = tap;
// Create a new AVAudioMix and assign it to our AVPlayerItem
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
audioMix.inputParameters = @[inputParams];
playerItem.audioMix = audioMix;
Pozdrowienia, Niek
mógłbyś dodać kod gdzie masz dostępu do buforów pikseli? –
Kod do odtwarzania wideo też może pomóc :) –
Zrobione. jakieś pomysły ? –