使用mp4v2将aac音频h264视频数据封装成mp4开发心得
這陣子在搗鼓一個將游戲視頻打包成本地可播放文件的模塊。開始使用avi作為容器,弄了半天無奈avi對aac的支持實在有限,在播放時音視頻時無法完美同步。
關于這點avi文檔中有提到:
For AAC, one RAW AAC frame usually spans over 1024 samples. However, depending on
the source container (e.g. ADTS), it is theoretically possible that you are not able to extract
packets of equal duration from your source le. In this case, it is highly recommended not
to mux the AAC stream into AVI, but report a fatal error instead.
因此建議大家不要用avi打包aac,如果實在需要avi格式,可以換成mp3。
言歸正傳,下面重點說說mp4打包時遇到的幾個問題,希望對后來開發這方面的朋友能有幫助,少走彎路。
首先需要下載編譯開源的mp4v2庫。這里一般沒什么問題,值得一提的是,mp4v2靜態庫會導出函數符號。如果你想讓程序瘦身,可以這么做在windows的工程屬性中去掉MP4V2_EXPORTS預定義,添加MP4V2_USE_STATIC_LIB,這樣最終的程序可以小100多KB。
mp4v2在vc2008下編譯release版會在link時出現link內部錯誤(我遇到了,不知道其他人是否也遇到),需要在工程中去掉link時優化,再編譯即可。
使用mp4v2打包音視頻的具體步驟網上已經有很多例子,不再此啰嗦了,就說說需要注意的幾點吧。
1、音頻aac不需要包含adts頭,即在設置faac選項時:
struConfig.outputFormat = 0; /* Bitstream output format (0 = Raw; 1 = ADTS) */
如果你包含了這個頭,我測試下來迅雷播放器可以支持,但是百度影音、暴風影音放出來沒聲音。(ps,我整個開發過程下來迅雷播放器支持度最好,百度和暴風影音在格式設置錯誤情況下會出現崩潰和無聲音現象,絕非廣告)
2、MP4AddAudioTrack時,注意第三個參數sampleDuration要設置正確。如果每次添加的音頻數據樣本數相同,可以在這里先設置好。mp4v2建議把刻度設置為采樣率,這樣第三個參數就是每次送入數據塊的樣本數。這個數據可以在編碼aac時得到,faacEncOpen返回的input樣本數如果是2048,那么雙通道實際就是1024。
3、設置完這些參數后,本以為萬事大吉,但是播放器放出來還是沒有聲音。那就需要用MP4SetTrackESConfiguration設置音頻解碼信息。音頻解碼信息怎么來,可以從faac里faacEncGetDecoderSpecificInfo得到,下面是我的代碼:
unsigned int CAACCodec::GetDecoderSpecificInfo(unsigned char * & apInfo)
{
? ? if ( m_hCodec == NULL )
? ? {
? ? ? ? return 0;
? ? }
? ? unsigned long uLen = 0;
? ? faacEncGetDecoderSpecificInfo(m_hCodec, &apInfo, &uLen);
? ? return uLen;
}
將返回的信息,再用MP4SetTrackESConfiguration設置到音頻track里去就ok了。
這里有個問題還要注意下,解碼信息這塊內存,是faac用malloc方式分配出來的,所以你不要忘記free它,否則會造成內存泄露(雖然很小,才2字節)
?MP4V2 錄制mp4(h264+aac)視頻?
標簽: mp4v2 aac h264
2015-08-15 19:34 379人閱讀 評論(0) 收藏 舉報
?分類:
雜項(5)?
目錄(?)
[+]
MP4錄制程序是根據mpeg4ip中mpeg4ip-1.5.0.1\server\mp4live\file_mp4_recorder.cpp文件改的。程序支持h264+aac(raw 流)的寫入方式,用到了動態庫mp4v2-2.0.0,不要用mpeg4ip中那個較老的版本,因為在錄制大文件時會有效率問題,下面是一些mp4v2接口的簡介。
?
MP4FileHandle MP4Create (const char* fileName,uint32_t? flags)
功能:創建MP4文件句柄。
?返回:MP4文件句柄。
?參數:fileName 要錄制的MP4文件名;flags 創建文件類型,如果要創建普通文件用默認值0就可以,如要錄制大于4G的MP4文件此處要設置MP4_CREATE_64BIT_DATA。
?
bool MP4SetTimeScale( MP4FileHandle hFile, uint32_t value )
功能:設置時間標度。
返回:成功返回true,失敗返回false。
參數:hFile MP4文件句柄,value 要設置的值(每秒的時鐘ticks數)。
?
MP4TrackId MP4AddH264VideoTrack(MP4FileHandle hFile,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint32_t timeScale,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MP4Duration sampleDuration,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint16_t width,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint16_t height,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint8_t AVCProfileIndication,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint8_t profile_compat,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint8_t AVCLevelIndication,
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint8_t sampleLenFieldSizeMinusOne)
功能:添加h264視頻track。
返回:返回track id號。
參數:hFile MP4文件句柄,timeScale 視頻每秒的ticks數(如90000),sampleDuration 設置為 MP4_INVALID_DURATION,width height 視頻的寬高,AVCProfileIndication profile (baseline profile, main profile, etc. see),profile_compat compatible profile,AVCLevelIndication levels,sampleLenFieldSizeMinusOne 設置為3.
注意: AVCProfileIndication,profile_compat, AVCLevelIndication,這三個參數值是在h264流中得到的。
?
MP4TrackId MP4AddAudioTrack(
? ? ? ? MP4FileHandle hFile,
? ? ? ? uint32_t timeScale,
? ? ? ? MP4Duration sampleDuration,
? ? ? ? uint8_t audioType)
?功能:添加音頻(aac)track。
?返回:返回track id號。
?參數:hFile MP4句柄,timeScale音頻每秒的ticks數(如16000),下面兩參數設置為MP4_INVALID_DURATION和MP4_MPEG4_AUDIO_TYPE。
bool MP4SetTrackESConfiguration(
?? ? ? MP4FileHandle? hFile,
?? ? ? MP4TrackId ? ? trackId,
?? ? ? const uint8_t* pConfig,
?? ? ? uint32_t ? ? ? configSize );
?功能:設置音頻解碼信息(如果設置錯誤會導致沒有聲音)。
?返回:成功返回true,失敗返回false。
?參數:hFile 文件句柄,trackId 音頻的track id,pConfig 記錄解碼信息的二進制流,configSize 解碼串的長度。
?注意:mpeg4ip 使用faac進行aac音頻編碼的,在編碼時可以調用相應的函數得到二進制串pConfig和長度configSize,但是如果aac不是用faac編碼的,這是需要自己填充pConfig,可以參考faac的實現,下面是一個填充結構例子:
?
前五個字節為 AAC object types? LOW ? ? 2
接著4個字節為 碼率index? ? ? ? 16000? ? ? 8
接著4個字節為 channels 個數 ? ? ? ? ? ? ? ? 1
應打印出的正確2進制形式為? 00010 | 1000 | 0001 | 000
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2? ? ? ? ? 8? ? ? ? 1
bool MP4WriteSample(
? ? MP4FileHandle? hFile,
? ? MP4TrackId ? ? trackId,
? ? const uint8_t* pBytes,
? ? uint32_t ? ? ? numBytes,
? ? MP4Duration? ? duration DEFAULT(MP4_INVALID_DURATION),
? ? MP4Duration? ? renderingOffset DEFAULT(0),
? ? bool ? ? ? ? ? isSyncSample DEFAULT(true) );
功能:寫一幀視頻數據或寫一段音頻數據。
返回:成功返回true,失敗返回false。
參數:hFile 文件句柄,trackId 音頻或視頻的track id,pBytes為要寫的數據流指針,numBytes為數據字節長度,duration為前一視頻幀與當前視頻幀之間的ticks數,或這是前一段音頻數據和當前音頻數據之間的ticks。isSyncSample 對視頻來說是否為關鍵幀。
注意:1,duration這個參數是用來實現音視頻同步用的,如果設置錯了會造成音視頻不同步,甚至會出現crash現象(一般出現在調用MP4Close是crash)。 2,對于視頻流MP4WriteSample函數每次調用是錄制前一幀數據,用當前幀的時間戳和前一幀的時間戳計算duration值,然后把當前幀保存下來用做下次調用MP4WriteSample時用,寫音頻數據一樣。
?
?
void MP4AddH264SequenceParameterSet(
? ? MP4FileHandle? hFile,
? ? MP4TrackId ? ? trackId,
? ? const uint8_t* pSequence,
? ? uint16_t ? ? ? sequenceLen );
和
void MP4AddH264PictureParameterSet(
? ? MP4FileHandle? hFile,
? ? MP4TrackId ? ? trackId,
? ? const uint8_t* pPict,
? ? uint16_t ? ? ? pictLen );
功能:添加序列參數集,添加圖像參數集。
參數:hFile 文件句柄,trackId 視頻track id,pSequence和pPict為要寫入的序列圖像參數集的數據指針,sequenceLen和pictLen為串長度。
注意:當檢測到序列參數集或圖像參數集更新時要調用MP4AddH264SequenceParameterSet或MP4AddH264PictureParameterSet進行更新。
?
void MP4Close(
? ? MP4FileHandle hFile,
? ? uint32_t? ? flags DEFAULT(0) );
功能:關閉以打開的MP4文件。
參數:hFile 文件句柄,flags 是否允許在關閉MP4文件前做一些額外的優化處理。
注意:在錄制較小的MP4文件時可以把flags設置為默認值,如果錄制較大的文件最好把flags設置為MP4_CLOSE_DO_NOT_COMPUTE_BITRATE否則調用MP4Close函數會用掉很長的時間。
轉載自:http://blog.csdn.net/jwzhangjie/article/details/8782650
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
音頻編解碼·實戰篇(1)PCM轉至AAC(AAC編碼)
- 作者:柳大·Poechant
- 博客:blog.csdn.net/poechant
- 郵箱:zhongchao.ustc@gmail.com
- 日期:April 7th, 2012
這里利用FAAC來實現AAC編碼。
1 下載安裝 FAAC
這里的安裝過程是在 Mac 和 Linux 上實現的,Windows可以類似參考。
wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gz
tar zxvf faac-1.28.tar.gz
cd faac-1.28
./configure
make
sudo make install
如果才用默認的 configure 中的 prefix path,那么安裝后的 lib 和 .h 文件分別在/usr/local/lib和/usr/local/include,后面編譯的時候會用到。
如果編譯過程中發現錯誤:
mpeg4ip.h:126: error: new declaration ‘char* strcasestr(const char*, const char*)’
解決方法:
從123行開始修改此文件mpeg4ip.h,到129行結束。 修改前:
#ifdef __cplusplus
extern "C" {
#endif
char *strcasestr(const char *haystack, const char *needle);
#ifdef __cplusplus
}
#endif
修改后:
#ifdef __cplusplus
extern "C++" {
#endif
const char *strcasestr(const char *haystack, const char *needle);
#ifdef __cplusplus
}
#endif
2 FAAC API
2.1 Open FAAC engine
Prototype:
faacEncHandle faacEncOpen ? ? ? ? ? ? ? // 返回一個FAAC的handle
(? ? ? ? ? ? ? ? ? ?
? ? unsigned long ? nSampleRate,? ? ? ? // 采樣率,單位是bps
? ? unsigned long ? nChannels,? ? ? ? ? // 聲道,1為單聲道,2為雙聲道
? ? unsigned long ? &nInputSamples, ? ? // 傳引用,得到每次調用編碼時所應接收的原始數據長度
? ? unsigned long ? &nMaxOutputBytes? ? // 傳引用,得到每次調用編碼時生成的AAC數據的最大長度
);
2.2 Get/Set encoding configuration
Prototype:
獲取編碼器的配置:
faacEncConfigurationPtr faacEncGetCurrentConfiguration // 得到指向當前編碼器配置的指針
(
? ? faacEncHandle hEncoder? // FAAC的handle
);
設定編碼器的配置:
int FAACAPI faacEncSetConfiguration
(
? ? faacDecHandle hDecoder, ? ? ? ? // 此前得到的FAAC的handle
? ? faacEncConfigurationPtr config? // FAAC編碼器的配置
);
2.3 Encode
Prototype:
int faacEncEncode
(
? ? faacEncHandle hEncoder, ? ? // FAAC的handle
? ? short *inputBuffer, ? ? ? ? // PCM原始數據
? ? unsigned int samplesInput,? // 調用faacEncOpen時得到的nInputSamples值
? ? unsigned char *outputBuffer,// 至少具有調用faacEncOpen時得到的nMaxOutputBytes字節長度的緩沖區
? ? unsigned int bufferSize ? ? // outputBuffer緩沖區的實際大小
);
2.4 Close FAAC engine
Prototype
void faacEncClose
(
? ? faacEncHandle hEncoder? // 此前得到的FAAC handle
);
3 流程
3.1 做什么準備?
采樣率,聲道數(雙聲道還是單聲道?),還有你的PCM的單個樣本是8位的還是16位的?
3.2 開啟FAAC編碼器,做編碼前的準備
3.3 開始編碼
調用faacEncEncode,該準備的剛才都準備好了,很簡單。
3.4 善后
關閉編碼器,另外別忘了釋放緩沖區,如果使用了文件流,也別忘記了關閉。
4 測試程序
4.1 完整代碼
將PCM格式音頻文件/home/michael/Development/testspace/in.pcm轉至AAC格式文件/home/michael/Development/testspace/out.aac。
#include <faac.h>
#include <stdio.h>
typedef unsigned long ? ULONG;
typedef unsigned int? ? UINT;
typedef unsigned char ? BYTE;
typedef char? ? ? ? ? ? _TCHAR;
int main(int argc, _TCHAR* argv[])
{
? ? ULONG nSampleRate = 11025;? // 采樣率
? ? UINT nChannels = 1; ? ? ? ? // 聲道數
? ? UINT nPCMBitSize = 16;? ? ? // 單樣本位數
? ? ULONG nInputSamples = 0;
? ? ULONG nMaxOutputBytes = 0;
? ? int nRet;
? ? faacEncHandle hEncoder;
? ? faacEncConfigurationPtr pConfiguration;?
? ? int nBytesRead;
? ? int nPCMBufferSize;
? ? BYTE* pbPCMBuffer;
? ? BYTE* pbAACBuffer;
? ? FILE* fpIn; // PCM file for input
? ? FILE* fpOut; // AAC file for output
? ? fpIn = fopen("/home/michael/Development/testspace/in.pcm", "rb");
? ? fpOut = fopen("/home/michael/Development/testspace/out.aac", "wb");
? ? // (1) Open FAAC engine
? ? hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
? ? if(hEncoder == NULL)
? ? {
? ? ? ? printf("[ERROR] Failed to call faacEncOpen()\n");
? ? ? ? return -1;
? ? }
? ? nPCMBufferSize = nInputSamples * nPCMBitSize / 8;
? ? pbPCMBuffer = new BYTE [nPCMBufferSize];
? ? pbAACBuffer = new BYTE [nMaxOutputBytes];
? ? // (2.1) Get current encoding configuration
? ? pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
? ? pConfiguration->inputFormat = FAAC_INPUT_16BIT;
? ? // (2.2) Set encoding configuration
? ? nRet = faacEncSetConfiguration(hEncoder, pConfiguration);
? ? for(int i = 0; 1; i++)
? ? {
? ? ? ? // 讀入的實際字節數,最大不會超過nPCMBufferSize,一般只有讀到文件尾時才不是這個值
? ? ? ? nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn);
? ? ? ? // 輸入樣本數,用實際讀入字節數計算,一般只有讀到文件尾時才不是nPCMBufferSize/(nPCMBitSize/8);
? ? ? ? nInputSamples = nBytesRead / (nPCMBitSize / 8);
? ? ? ? // (3) Encode
? ? ? ? nRet = faacEncEncode(
? ? ? ? hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
? ? ? ? fwrite(pbAACBuffer, 1, nRet, fpOut);
? ? ? ? printf("%d: faacEncEncode returns %d\n", i, nRet);
? ? ? ? if(nBytesRead <= 0)
? ? ? ? {
? ? ? ? ? ? break;
? ? ? ? }
? ? }
? ? /*
? ? while(1)
? ? {
? ? ? ? // (3) Flushing
? ? ? ? nRet = faacEncEncode(
? ? ? ? hEncoder, (int*) pbPCMBuffer, 0, pbAACBuffer, nMaxOutputBytes);
? ? ? ? if(nRet <= 0)
? ? ? ? {
? ? ? ? ? ? break;
? ? ? ? }
? ? }
? ? */
? ? // (4) Close FAAC engine
? ? nRet = faacEncClose(hEncoder);
? ? delete[] pbPCMBuffer;
? ? delete[] pbAACBuffer;
? ? fclose(fpIn);
? ? fclose(fpOut);
? ? //getchar();
? ? return 0;
}
4.2 編譯運行
將上述代碼保存為“pcm2aac.cpp”文件,然后編譯:
g++ pcm2aac.cpp -o pcm2aac -L/usr/local/lib -lfaac -I/usr/local/include
運行:
./pcm2aac
然后就生成了out.aac文件了,聽聽看吧!~
5 Reference
-
轉載請注明來自柳大的CSDN博客:blog.csdn.net/poechant
轉載自:http://blog.csdn.net/poechant/article/details/7435054
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
??
Faac 編碼實時pcm流到aac流
分類: 多媒體開發2013-04-10 14:09 2843人閱讀 評論(3) 收藏 舉報
Faac
我的程序是根據faac 1.28 庫中的frontend目錄下的faac的例子改的。
下面是程序的運行流程:
首先調用faacEncHandle hEncoder=faacEncOpen(samplerate,channels,& samplesInput,
&maxBytesOutput);
1.打開aac編碼引擎,創建aac編碼句柄。
參數 samplerate 為要編碼的音頻pcm流的采樣率,channels為要編碼的音頻pcm流的的頻道數(原有的例子程序是從wav文件中讀出這些信息),sampleInput在編碼時要用到,意思是每次要編碼的采樣數,參數maxBytesOutput為編碼時輸出地最大字節數。
?
2.然后在設置一些編碼參數,如
int version=MPEG4;? ? //設置版本,錄制MP4文件時要用MPEG4
int objecttype=LOW;? ? //編碼類型
int midside=1;? ? ? ? ? //M/S編碼
int usetns=DEFAULT_TNS; ? //瞬時噪聲定形(temporal noise shaping,TNS)濾波器
int shortctl=SHORTCTL_NORMAL;
int inputformat=FAAC_INPUT_16BIT;? //輸入數據類型
int outputformat=RAW_STREAM; //錄制MP4文件時,要用raw流。檢驗編碼是否正確時可設
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //置為adts傳輸流,把aac 流寫入.aac文件中,如編碼正確
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //用千千靜聽就可以播放。
其他的參數可根據例子程序設置。
設置完參數后就調用faacEncSetConfiguration(hEncoder, aacFormat)設置編碼參數。
3.如編碼完的aac流要寫入MP4文件時,要調用
faacEncGetDecoderSpecificInfo(hEncoder,&(ASC), &(ASCLength));//得到解碼信息
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //(mpeg4ip mp4 錄制使用)
此函數支持MPEG4版本,得到的ASC 和ACSLength 數據在錄制MP4(mpegip庫)文件時用。
?
4.然后就是編碼了,每次從實時的pcm音頻隊列中讀出samplesInput* channels*(量化位數/8),
字節數的pcm數據。然后再把得到pcm流轉變一下存儲位數,我是轉化為16位的了,這部分
可以根據例子程序寫一個函數,這是我寫的一個,
size_t read_int16(AACInfo *sndf, int16_t *outbuf, size_t num, unsigned char *inputbuf)
{
?? ? ? size_t i=0,j=0;
?? ? ? unsigned char bufi[8];
?? ? ? while(i<num)
?? ? ? {
? ? ? ? ? ? ? ? memcpy(bufi,inputbuf+j,sndf->samplebytes);
?? ? ? ? ? ? ? j+=sndf->samplebytes;
? ? ? ? ? ? ? int16_t s=((int16_t*)bufi)[0];
?? ? ? ? ? ? outbuf[i]=s;
?? ? ? ? ? ? i++;
?? ? ? }
?? ? ? return i;
}
也可以寫一個read_float32(AACInfo *sndf, float *outbuf, size_t num ,unsigned char *inputbuf),
和size_t read_int24(AACInfo *sndf, int32_t *outbuf, size_t num, unsigned char *inputbuf)。
處理完數據轉換后就調用
bytesWritten = faacEncEncode(hEncoder,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (int *)pcmbuf,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? samplesInput,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? outbuff,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? maxbytesoutput);
進行編碼,pcmbuf為轉換后的pcm流數據,samplesInput為調用faacEncOpen時得到的輸入采樣數,outbuff為編碼后的數據buff,maxbytesoutput為調用faacEncOpen時得到的最大輸出字節數。然后每次從outbuff中得到編碼后的aac數據流,放到數據隊列就行了,如果還要錄制MP4文件,在編碼完samplesInput(一幀)個采樣數時,打上時間戳(mpegip庫用于音視頻同步)后再放到輸出隊列中。如果想測試看編碼的aac流是否正確,設置輸出格式為ADTS_STREAM,把aac數據寫入到.aac文件中,看能否用千千靜聽播放。
5.釋放資源,調用faacEncClose(hEncoder);就行了
Mp4v2實現h264+aac打包成Mp4視頻文件
分類: 數據庫/ DB2/ 文章
使用mp4v2實現錄制mp4視頻,需要準備如下信息:
1、獲取mp4v2源碼并編譯成庫文件,對于mp4v2的編譯可以看前面的文章android 編譯mp4v2 2.0.0生成動態庫 ;
2、獲取h264數據中的sps和pps數據,如果不會的話可以查看前面的文章? 點擊打開鏈接;
3、獲取音頻解碼信息,在調用MP4SetTrackESConfiguration使用,具體的獲取方式一種通過faac獲取,方法faacEncGetDecoderSpecificInfo(hEncoder,&(ASC), &(ASCLength));//得到解碼信息另一種查看aac音頻源碼,并并對照aac的adts頭格式分析:
查看文本打印
查看文本打印
所以為(20,8)
4、規定時間刻度問題,一般網上都是設置90000,這個90000是指1秒的tick數,其實也就是把1秒中分為90000份,在添加音視頻的函數中
durationMP4_INVALID_DURATION
查看文本打印
查看文本打印
其中duration這個參數是指視頻幀存在的時間,在90000這個刻度上存在的時間,如果用戶確定錄像時的音頻視頻幀是按固定速率的,那么在這里可以設置MP4_INVALID_DURATION,這時mp4v2就會使用下面的函數中的時間刻度
視頻:
查看文本打印
查看文本打印
總結
以上是生活随笔為你收集整理的使用mp4v2将aac音频h264视频数据封装成mp4开发心得的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是流浪啊? 求解
- 下一篇: H.264中IDR帧和I帧区别