2015-03-13 9 views
24

Diese Frage scheint in den letzten paar Jahren mehrmals gestellt worden zu sein, aber keine hat dafür eine Antwort. Ich versuche PCM-Daten von HLS zu verarbeiten und ich muss AVPlayer verwenden.PCM-Daten von HLS von AVPlayer erhalten

dieser Beitrag tippt die lokalen Dateien https://chritto.wordpress.com/2013/01/07/processing-avplayers-audio-with-mtaudioprocessingtap/

und diese Hahn Arbeit mit Remote-Dateien aber nicht mit .m3u8 HLS-Dateien. http://venodesigns.net/2014/01/08/recording-live-audio-streams-on-ios/

Ich kann beiden ersten Titel in der Playlist abspielen, aber es startet nicht die benötigten Callbacks die pcm zu bekommen, wenn die Datei lokal oder remote ist (nicht streamen) ich noch die pcm bekommen kann, aber es ist die HLS nicht funktioniert und ich brauche HLS

Arbeits

hier ist mein Code

//avplayer tap try 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    NSURL*testUrl= [NSURL URLWithString:@"http://playlists.ihrhls.com/c5/1469/playlist.m3u8"]; 

    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:testUrl]; 
    self.player = [AVPlayer playerWithPlayerItem:item]; 

    // Watch the status property - when this is good to go, we can access the 
    // underlying AVAssetTrack we need. 
    [item addObserver:self forKeyPath:@"status" options:0 context:nil]; 

} 

-(void)observeValueForKeyPath:(NSString *)keyPath 
ofObject:(id)object 
change:(NSDictionary *)change 
context:(void *)context 
{ 
    if(![keyPath isEqualToString:@"status"]) 
     return; 

    AVPlayerItem *item = (AVPlayerItem *)object; 
    if(item.status != AVPlayerItemStatusReadyToPlay) 
     return; 

    NSArray *tracks = [self.player.currentItem tracks]; 
    for(AVPlayerItemTrack *track in tracks) { 
     if([track.assetTrack.mediaType isEqualToString:AVMediaTypeAudio]) { 
      NSLog(@"GOT DAT FUCKER"); 
      [self beginRecordingAudioFromTrack:track.assetTrack]; 
      [self.player play]; 
     } 
    } 
} 

- (void)beginRecordingAudioFromTrack:(AVAssetTrack *)audioTrack 
{ 
    // Configure an MTAudioProcessingTap to handle things. 
    MTAudioProcessingTapRef tap; 
    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; 

    OSStatus err = MTAudioProcessingTapCreate(
               kCFAllocatorDefault, 
               &callbacks, 
               kMTAudioProcessingTapCreationFlag_PostEffects, 
               &tap 
              ); 

    if(err) { 
     NSLog(@"Unable to create the Audio Processing Tap %d", (int)err); 
     return; 
    } 

    // Create an AudioMix and assign it to our currently playing "item", which 
    // is just the stream itself. 
    AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; 
    AVMutableAudioMixInputParameters *inputParams = [AVMutableAudioMixInputParameters 
                audioMixInputParametersWithTrack:audioTrack]; 

    inputParams.audioTapProcessor = tap; 
    audioMix.inputParameters = @[inputParams]; 
    self.player.currentItem.audioMix = audioMix; 
} 

void process(MTAudioProcessingTapRef tap, CMItemCount numberFrames, 
      MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut, 
      CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut) 
{ 
    OSStatus err = MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, 
                 flagsOut, NULL, numberFramesOut); 
    if (err) NSLog(@"Error from GetSourceAudio: %d", (int)err); 

    NSLog(@"Process"); 

} 

void init(MTAudioProcessingTapRef tap, void *clientInfo, void **tapStorageOut) 
{ 
    NSLog(@"Initialising the Audio Tap Processor"); 
    *tapStorageOut = clientInfo; 
} 

void finalize(MTAudioProcessingTapRef tap) 
{ 
    NSLog(@"Finalizing the Audio Tap Processor"); 
} 

void prepare(MTAudioProcessingTapRef tap, CMItemCount maxFrames, const AudioStreamBasicDescription *processingFormat) 
{ 
    NSLog(@"Preparing the Audio Tap Processor"); 
} 

void unprepare(MTAudioProcessingTapRef tap) 
{ 
    NSLog(@"Unpreparing the Audio Tap Processor"); 
} 

void init heißt void prepare und process hat auch genannt werden.

Wie kann ich das tun?

+0

Hattest du Erfolg damit? Ich kämpfe mit dem gleichen Problem. – danielbuechele

+0

@danielbuechele leider kein Glück, wir mussten das Problem mit einem anderen Winkel angehen, wir haben die Verbindung proxied, so konnten wir die '.m4a' Dateien in unseren eigenen Codec einspeisen, um das PCM zu analysieren und dann die m4a Chunks an einen Spieler zu füttern. Es war wirklich sehr hacky. –

+0

Auch wenn es nicht beantwortet wird, möchte ich auf eine Frage von mir verweisen, die vor mehr als 4 Jahren sehr eng verwandt ist. Es gibt jemanden, der sagt, dass er tatsächlich erfolgreich war, aber es geheim gehalten hat, wie er es getan hat :( https://stackoverflow.com/questions/19403584/avplayer-hls-live-stream-level-meter-display-fft-data –

Antwort

-3

empfohlen I Novocaine

Wirklich schnell Audio-in iOS und Mac OS X Audio Units hart ist, zu benutzen und werden Sie vernarbt und blutig verlassen. Was früher Tage gedauert hat, kann jetzt mit ein paar Zeilen Code erledigt werden.

+0

Jedes Anwendungsbeispiel? – Robert

+0

Nach einigen Untersuchungen hat Novocaine keinen einfachen Weg, um beispielsweise die Rohdaten von einer Remote-M3u8-URL zu bekommen, also ist es definitiv keine Antwort auf die Frage des OP. –

+1

Novocaine ist keine Lösung für Die gestellte Frage: Nach meiner Forschung zu diesem Thema gibt es keine bekannte Methode zur Extraktion von PCM-Samples, die von AVPlayer bei der Wiedergabe von HLS verwendet werden. –

Verwandte Themen