1:音视频同步原理
每一帧音频或视频都有一个持续时间:duration:
采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。
。正常人听觉的频率范围大约在20Hz~20kHz之间,根据奈奎斯特采样理论,为了保证声音不失真,采样频率应该在40kHz左右。常用的音频采样频率有8kHz、
11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采样频率,还可以达到DVD的音质
对采样率为44.1kHz的AAC音频进行解码时,一帧的解码时间须控制在23.22毫秒内。
背景知识:
(一个AAC原始帧包含一段时间内1024个采样及相关数据)
分析:
1) AAC
音频帧的播放时间=一个AAC帧对应的采样样本的个数/采样频率(单位为s)
一帧 1024个 sample。采样率 Samplerate 44100KHz,每秒44100个sample, 所以根据公式
当前AAC一帧的播放时间是= 1024*1000000/44100= 22.32ms(单位为ms)
2) MP3
mp3 每帧均为1152个字节, 则:
frame_duration = 1152 * 1000000 / sample_rate
例如:sample_rate = 44100HZ时,计算出的时长为26.122ms,这就是经常听到的mp3每帧播放时间固定为26ms的由来。
3)H264
视频的播放时间跟帧率有关 frame_duration = 1000/fps
例如:fps = 25.00 ,计算出来的时常为40ms,这就是同行所说的40ms一帧视频数据。
由此得到了每一帧数据的持续时间,音视频交叉存储在容器中:一个时间轴:
时间轴:0
音频:
视频:
即视频的持续时间相加 和音频的持续时间相加作比较,谁小写入哪个。
2:pts:帧的显示顺序(注意是顺序不是时间),这里暂时用不到,用到再说明。
3:dts:帧的解码顺序(注意是顺序不是时间),这里暂时用不到,用到再说明。
4:同步方式有三种:
1:)同步视频到音频
2:)同步音频到视频
3:)同步两者到时钟
下面了解下具体遇到要注意的地方:
1:script tag中可以存放我见过的有30多种信息,这里只写入12种:
//duration,width,height,videodatarate,framerate,videocodecid,audiosamplerate,audiosamplesize,stereo,audiocodecid,filesize,keyframe 共12个
值得注意的是keyframe这个信息,里面有两个数组:filepositions,times,这两个数组表示关键帧在文件中的位置,和时间即上面算出来的时间戳。
有多少个关键帧就需要有多少组这样的信息。
2:由于在读取H264文件的时候关键帧的多少是不固定了,因此需要遍历一下H264文件才能查找到多少关键帧,代码如下:
这里还要讲到,为什么要先遍历H264文件,因为scritp tag 一般在flv文件的第一个tag,他的大小如果不固定,没有办法向下写video tag 和audio tag,所以
要算出大小,具体的大小代码:
3:同时音频AAC也需要读取7个字节的头,将采样率,和声道取出,然后才能做下面的操作,audio tag config需要这些参数,代码:
4: video tag config 的参数需要sps,pps 这些信息要通过判断视频帧的类型来取出,代码:
5:在循环存储音视频tag的时候 要注意,判断帧类型如果是 SEI,SPS,PPS,则不写入video tag中,时间戳也不向上写,代码:
6:音频的采样率,声道是用下标表示的,config中的下标和tag中的不一样,一定要注意:
tag中:
SoundRate UB[2]
0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHz
Sampling rate
For AAC: always 3
SoundType UB[1]
0 = sndMono
1 = sndStereo
Mono or stereo sound
For Nellymoser: always 0
For AAC: always 1
config中:
SoundType
注:本程序的demo地址:http://download.csdn.net/detail/zhuweigangzwg/5522123
交流请加QQ:379969650