Questa domanda sembra essere stata posta alcune volte negli ultimi anni, ma nessuno ha una risposta in proposito. Sto cercando di elaborare i dati PCM da HLS e devo usare AVPlayer.Ottenere dati PCM di HLS da AVPlayer
questo post rubinetti i file locali https://chritto.wordpress.com/2013/01/07/processing-avplayers-audio-with-mtaudioprocessingtap/
e questo rubinetto lavoro con i file remoti, ma non con i file .m3u8 HLS. http://venodesigns.net/2014/01/08/recording-live-audio-streams-on-ios/
posso giocare prime due tracce nella playlist, ma non avvia il callback necessarie per ottenere il PCM, quando il file è locale o remoto (non streaming) posso ancora ottenere il PCM, ma è la HLS non funziona e ho bisogno di lavorare HLS
qui è il mio codice
//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
si chiama void prepare
e process
deve essere chiamato pure.
come posso fare questo?
Hai avuto successo con questo? Sto lottando con lo stesso problema. – danielbuechele
@danielbuechele sfortunatamente nessuna fortuna, abbiamo dovuto affrontare il problema con un'angolazione diversa, abbiamo proxy la connessione in modo da poter alimentare i file '.m4a' nel nostro codec per analizzare il PCM, quindi inviare i pezzi m4a a un giocatore. E 'stato davvero hacky però. –
Anche se non viene data una risposta, vorrei fare riferimento a una mia domanda risalente a oltre 4 anni fa, che è strettamente correlata. C'è qualcuno che dice che in realtà ci è riuscito, ma lo ha tenuto segreto, come l'ha fatto :( https://stackoverflow.com/questions/19403584/avplayer-hls-live-stream-level-meter-display-fft-data –