2013-07-15 3 views
10

Я сделал видеопроигрыватель, который анализирует аудио- и видеодорожки в реальном времени с видео, которое в данный момент воспроизводится. Видеозаписи хранятся на устройстве iOS (в папке «Документы приложений»).iOS: аудио-видео-переход от Airplay

Все это работает нормально. Я использую MTAudioProcessingTap, чтобы получить все звуковые сэмплы и сделать несколько FFT, и я анализирую видео, просто скопировав пиксельные буферы из текущего воспроизводимого CMTime (свойство AVTlayer currentTime). Как я уже сказал, это прекрасно работает.

Но теперь я хочу поддержать Airplay. Просто сама трансляция не сложна, но мои краны перестают работать, как только Airplay переключается, и видео воспроизводится на ATV. Так или иначе, MTAudioProcessingTap не будет обрабатываться, а пиксельные буферы все пустые ... Я не могу добраться до данных.

Есть ли способ для доступа к этим данным?

Чтобы получить пиксельные буферы, я просто запускаю событие каждые несколько миллисекунд и извлекаю текущее время проигрывателя. Тогда:

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); 

Где tempAddress мой pixelbuffer и videoOutput является экземпляром AVPlayerItemVideoOutput.

Для аудио, я использую:

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; 

С уважением, Ниекома

+0

Не могли бы вы добавить код, в котором вы обращаетесь пиксельных буферов? –

+0

И код для воспроизведения видео тоже может помочь :) –

+0

Готово. Есть предположения ? –

ответ

-2

Здесь решением:

это реализовать AirPlay, я использую этот код только для аудио на моем приложении I не знаю, можете ли вы улучшить видео, но можете попробовать;)

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]; 
} 

А если вы используете трансляцию в приятном исполнении для управления LockScreen, ArtWork, Stop/play, Title ecc.

В DetailViewController от вас использования плеера этот код:

- (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}; 

    } 

} 

Надежда этот код может помочь вам;)

+0

Использование airplay - не проблема, но анализ аудио и видео данных в реальном времени. –