将VTCompressionSession中的压缩帧与音频数据复用到用于网络流的MPEG2-TS容器中

时间:2014-12-06 18:46:17

标签: ios audio video-streaming h.264 muxer

我正在开展一个涉及从iOS8中的VTCompressionSession抓取H.264编码帧的项目,将来自麦克风的实时AAC或PCM音频复制到可播放的MPEG2-TS中并通过插槽实现流式传输最短延迟的时间(即:(几乎)没有缓冲)。

在观看了iOS8中新的VideoToolbox的演示文稿并进行了一些研究后,我想可以安全地假设:

  • 你从VTCompressionSession获得的编码帧不是附件B格式,所以我需要以某种方式对它们进行转换(到目前为止我所看到的所有解释都太模糊了,所以我' m不确定你是如何做到这一点的(即:用长度标题&#34替换" 3或4字节标题;)。

  • 从VTCompressionSession获得的编码帧实际上是一个基本流。因此,首先我需要将它们转换为分组基本流,然后才能进行多路复用。

  • 我还需要来自麦克风数据的AAC或PCM基本流(我认为PCM会更容易,因为不涉及编码)。我不知道该怎么做。

  • 为了复用Packetized Elementary Streams,我还需要一些像libmpegts这样的库。或者也许是ffmpeg(通过使用libavcodec和libavformat库)。

我对此很陌生。我可以就实现这一目标的正确方法获得一些建议吗?

使用Apple API(如AVFoundation)有更简单的方法来实现吗?

我可以采取任何类似的项目作为参考吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

  

为了复用Packetized Elementary Streams,我还需要一些像libmpegts这样的库。或者也许是ffmpeg(通过使用libavcodec和libavformat库)。

从我可以收集的内容来看,没有办法将TS与AVFoundation或相关框架进行复用。虽然它似乎可以手动完成,但我正在尝试使用Bento4 library来完成与您相同的任务。我猜libmpegts,ffmpeg,GPAC,libav或任何其他类似的库也会起作用,但我不喜欢他们的API。

基本上,我正在关注Mp42Ts.cpp,忽略了Mp4部分,只看着Ts写作部分。

这个StackOverflow question概述了如何为视频提供视频,以及如何为其提供音频的实现。如果您有任何疑问,请告诉我一个更具体的问题。

我希望这为你提供了一个很好的起点。

  

我还需要来自麦克风数据的AAC或PCM基本流(我认为PCM会更容易,因为不涉及编码)。我不知道该怎么做。

将麦克风数据作为AAC获取非常简单。像这样:

AVCaptureDevice *microphone = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
_audioInput = [AVCaptureDeviceInput deviceInputWithDevice:microphone error:&error];

if (_audioInput == nil) {
    NSLog(@"Couldn't open microphone %@: %@", microphone, error);
    return NO;
}

_audioProcessingQueue = dispatch_queue_create("audio processing queue", DISPATCH_QUEUE_SERIAL);

_audioOutput = [[AVCaptureAudioDataOutput alloc] init];
[_audioOutput setSampleBufferDelegate:self queue:_audioProcessingQueue];


NSDictionary *audioOutputSettings = @{
    AVFormatIDKey: @(kAudioFormatMPEG4AAC),
    AVNumberOfChannelsKey: @(1),
    AVSampleRateKey: @(44100.),
    AVEncoderBitRateKey: @(64000),
};

_audioWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings];
_audioWriterInput.expectsMediaDataInRealTime = YES;
if(![_writer canAddInput:_audioWriterInput]) {
    NSLog(@"Couldn't add audio input to writer");
    return NO;
}
[_writer addInput:_audioWriterInput];

[_captureSession addInput:_audioInput];
[_captureSession addOutput:_audioOutput];

- (void)audioCapture:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    /// sampleBuffer contains encoded aac samples.
}

我猜你已经为你的相机使用了AVCaptureSession;您可以为麦克风使用相同的捕获会话。