2013-07-15 21 views
10

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

+0

mógłbyś dodać kod gdzie masz dostępu do buforów pikseli? –

+0

Kod do odtwarzania wideo też może pomóc :) –

+0

Zrobione. jakieś pomysły ? –

Odpowiedz

-2

Oto rozwiązanie:

to jest wdrożenie AirPlay, używam tego kodu tylko dla audio w moim app nie wiem, czy możesz poprawić film, ale możesz spróbować;)

Na AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

    [RADStyle applyStyle]; 
    [radiosound superclass]; 
    [self downloadZip]; 

    NSError *sessionError = nil; 
    [[AVAudioSession sharedInstance] setDelegate:self]; 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError]; 
    [[AVAudioSession sharedInstance] setActive:YES error:nil]; 

    UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback; 
    AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory); 

    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride); 

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 
} 

An, jeśli korzystasz z funkcji Airplay w celu implementacji kontrolki LockScreen, ArtWork, Stop/Play, Tytuł ecc.

W DetailViewController z was odtwarzacza użyć tego kodu:

- (BOOL)canBecomeFirstResponder { 

    return YES; 
} 
- (void)viewDidAppear:(BOOL)animated { 

    [super viewDidAppear:animated]; 
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 
    [self becomeFirstResponder]; 

    NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: (self.saved)[@"image"]]]; 

    if (imageData == nil){ 

    MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter]; 
    MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"lockScreen.png"]]; 

    infoCenter.nowPlayingInfo = @{MPMediaItemPropertyTitle: saved[@"web"],MPMediaItemPropertyArtist: saved[@"title"], MPMediaItemPropertyArtwork:albumArt}; 

    } else { 

     MPNowPlayingInfoCenter *infoCenter = [MPNowPlayingInfoCenter defaultCenter]; 
     MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageWithData:imageData]]; 

     infoCenter.nowPlayingInfo = @{MPMediaItemPropertyTitle: saved[@"link"],MPMediaItemPropertyArtist: saved[@"title"], MPMediaItemPropertyArtwork:albumArt}; 

    } 

} 

Nadzieja kod ten może pomóc;)

+0

Użycie funkcji Airplay nie stanowi problemu, ale analizowanie danych audio i wideo w czasie rzeczywistym odbywa się. –

Powiązane problemy