基于live555的rtsp播放器之十八:G711a/G711u/G726转AAC

封装格式的主要作用是把视频码流和音频码流按照一定的格式存储在一个文件中。现如今流行的封装格式如下表所示:

此表来自雷神:[总结]视音频编解码技术零基础学习方法,由表可见:
1.除了AVI之外,其他封装格式都支持流媒体,即可以“边下边播”。有些格式更“万能”一些,支持的视音频编码标准多一些,比如MKV。而有些格式则支持的相对比较少,比如说RMVB。
2.几乎所有封装格式都音频编码都支持AAC。

雷神博客中还有关于AAC、MP3和WMA等主流音频编码格式的对比,对比结果表明在码率较低的情况下,不同编码方案的音频的音质排序为:

AAC+> MP3PRO > AAC > RealAudio > WMA > MP3
因此,在录制mp4的时候,都是先把G711a/G711u/G726解码为PCM,然后再编码成AAC。
实现的方法有两种:
1.使用ffmpeg先解码再编码。
2.使用开源库EasyAACEncoder,EasyAACEncoder 是EasyDarwin开源流媒体服务团队整理、开发的一款音频转码到AAC的工具库,

已标记关键词 清除标记
相关推荐
我用live555搭了一个rtsp服务端,开了两个队列,一个存放已经编码的H264数据,一个存放已编码的AAC数据。视频帧率15,音频采样率8000。开两个OnDemandMediaSubsession分别处理音频和视频,然后再把他们加到ServerMediaSession。继承Framesource,重写doGetNextFrame,从队列取数据。问题来了,我这样做,只能流畅播放2分钟左右,之后,视频流就会丢帧很严重,画面卡死。然而,我单独播放视频流,或者音频流都是没有问题的。我用的是VLC播放器。各路大神,能指教指教么? AACFrameSource(): void IPCAACAudioFramedSource::doGetNextFrame() { unsigned int frame_length; memset(data, 0, AUDIO_BUFFER_SIZE); memset(ptv, 0, sizeof(ptv)); fGetAACFrameFunc(data, &frame_length, ptv); //从队列取AAC 数据 //memcpy(fTo, adts_header, 7); memcpy (fTo, data, frame_length); fFrameSize = frame_length; // Next, read the raw frame data into the buffer provided: if (fFrameSize> fMaxSize) { fNumTruncatedBytes = fFrameSize - fMaxSize; fFrameSize = fMaxSize; } else { fNumTruncatedBytes = 0; } // Set the 'presentation time': if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) { // This is the first frame, so use the current time: gettimeofday(&fPresentationTime, NULL); } else { // Increment by the play time of the previous frame: // fuSecsPerFrame // = (1024/*samples-per-frame*/*1000000) / fSamplingFrequency/*samples-per-second*/; unsigned uSeconds = fPresentationTime.tv_usec + fuSecsPerFrame; fPresentationTime.tv_sec += uSeconds/1000000; fPresentationTime.tv_usec = uSeconds%1000000; } //gettimeofday(&fPresentationTime, NULL); fDurationInMicroseconds = fuSecsPerFrame; // Switch to another task, and inform the reader that he has data: nextTask() = envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)FramedSource::afterGetting, this); } H264FrameSource(): void IPCH264FramedSource::doGetNextFrame() { fFrameSize = 0; unsigned int len = 0; memset(frameData, 0, BUFFER_SIZE); if(m_getframefunc) { //从视频数据队列取数据 m_getframefunc(frameData, &len, m_nNeedIFrameCount, ptv, findex); } else { printf("not have getframefunc!!!\n"); return; } fFrameSize = len - 4; //使用H264VideoStreamDiscreteFramer,故没有前4个字节头 if (fFrameSize > fMaxSize) { fNumTruncatedBytes = fFrameSize - fMaxSize; fFrameSize = fMaxSize; } else { fNumTruncatedBytes = 0; } memcpy(fTo,&frameData[4],fFrameSize); gettimeofday(&fPresentationTime, NULL); fDurationInMicroseconds = 0; nextTask() = envir().taskScheduler().scheduleDelayedTask(0, (TaskFunc*)FramedSource::afterGetting, this); } unsigned int AMASSIPCH264FramedSource::maxFrameSize() const { return 1024*200; }
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付 29.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值