在ios上解码hls流中的音频样本?
我试图在iOS设备上解码来自远程HLS(m3u8)流的音频样本,以便进一步处理数据,例如记录到文件中。 作为参考流使用 通过使用AVURLAsset和AVPlayer,我可以在CALayer上预览视频。 我还可以使用AVPlayerItemVideoOutput获得原始视频数据(CVPixelBuffer)。通过iOS设备的扬声器也可以听到音频 这是我目前正在为AVURLAsset和AVPlayer使用的代码:在ios上解码hls流中的音频样本?,ios,m3u8,http-live-streaming,Ios,M3u8,Http Live Streaming,我试图在iOS设备上解码来自远程HLS(m3u8)流的音频样本,以便进一步处理数据,例如记录到文件中。 作为参考流使用 通过使用AVURLAsset和AVPlayer,我可以在CALayer上预览视频。 我还可以使用AVPlayerItemVideoOutput获得原始视频数据(CVPixelBuffer)。通过iOS设备的扬声器也可以听到音频 这是我目前正在为AVURLAsset和AVPlayer使用的代码: NSURL* url = [NSURL URLWithString:@"http:/
NSURL* url = [NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
NSString *tracksKey = @"tracks";
[asset loadValuesAsynchronouslyForKeys:@[tracksKey] completionHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSError* error = nil;
AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error];
if (status == AVKeyValueStatusLoaded) {
NSDictionary *settings = @
{
(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA),
@"IOSurfaceOpenGLESTextureCompatibility": @YES,
@"IOSurfaceOpenGLESFBOCompatibility": @YES,
};
AVPlayerItemVideoOutput* output = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:settings];
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addOutput:output];
AVPlayer* player = [AVPlayer playerWithPlayerItem:playerItem];
[player setVolume: 0.0]; // no preview audio
self.playerItem = playerItem;
self.player = player;
self.playerItemVideoOutput = output;
AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer: player];
[self.preview.layer addSublayer: playerLayer];
[playerLayer setFrame: self.preview.bounds];
[playerLayer setVideoGravity: AVLayerVideoGravityResizeAspectFill];
[self setPlayerLayer: playerLayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemNewAccessLogEntry:) name:AVPlayerItemNewAccessLogEntryNotification object:self.playerItem];
[_player addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:&PlayerStatusContext];
[_playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:&PlayerItemStatusContext];
[_playerItem addObserver:self forKeyPath:@"tracks" options:0 context:nil];
}
});
}];
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (self.player.status == AVPlayerStatusReadyToPlay && context == &PlayerStatusContext) {
[self.player play];
}
}
要获取HLS流的原始视频数据,我使用:
CVPixelBufferRef buffer = [self.playerItemVideoOutput copyPixelBufferForItemTime:self.playerItem.currentTime itemTimeForDisplay:nil];
if (!buffer) {
return;
}
CMSampleBufferRef newSampleBuffer = NULL;
CMSampleTimingInfo timingInfo = kCMTimingInfoInvalid;
timingInfo.duration = CMTimeMake(33, 1000);
int64_t ts = timestamp * 1000.0;
timingInfo.decodeTimeStamp = CMTimeMake(ts, 1000);
timingInfo.presentationTimeStamp = timingInfo.decodeTimeStamp;
CMVideoFormatDescriptionRef videoInfo = NULL;
CMVideoFormatDescriptionCreateForImageBuffer(
NULL, buffer, &videoInfo);
CMSampleBufferCreateForImageBuffer(kCFAllocatorDefault,
buffer,
true,
NULL,
NULL,
videoInfo,
&timingInfo,
&newSampleBuffer);
// do something here with sample buffer...
CFRelease(buffer);
CFRelease(newSampleBuffer);
现在我也想访问原始音频数据,但到目前为止运气不佳。
我尝试使用MTAudioProcessingTap,如下所述:不幸的是,我无法让它正常工作。我成功访问了AVPlayerItem的底层assetTrack,但从未调用MTAudioProcessingTap的回调方法“prepare”和“process”。我不确定我是否走对了这条路 AVPlayer通过扬声器播放流的音频,因此在内部音频似乎可以作为原始音频数据使用。是否可以访问原始音频数据?如果AVPlayer无法实现,是否有其他方法
如果可能的话,我不想使用ffmpeg,因为iOS设备的硬件解码器应该用于流的解码。您好,欢迎使用Stack Overflow。为了帮助您,我们需要您向我们提供更多信息(例如解决方案的外观,以及您编写的任何相关代码),并与我们分享您在该主题上已经完成的研究(因此我们不会重复您的工作)。我们确实希望您自己设计和编写此文件(我们不会为您完成工作),因此希望您在来寻求我们的帮助之前,至少尝试过使其正常工作。谢谢您的指点。我添加了更详细的描述。你解决了这个问题吗?