資源簡介
在一些視頻服務(wù)中,如VOD推流的快進(jìn)、快退中,經(jīng)常需要快速從ts節(jié)目流中找出I幀(I-frame)來,以便推流服務(wù)器可以推送只包含視頻畫面而沒有聲音的ts數(shù)據(jù)到終端,而終端并不需要做任何特殊處理,即可實(shí)現(xiàn)快進(jìn)/快退的畫面效果。
因此,實(shí)現(xiàn)上需要做到以下三點(diǎn):
1、要找到I幀
2、確保找出來的I幀數(shù)據(jù)前后都要完整,即符合MPEG-2的188長度的封包格式
3、去掉其中的音頻數(shù)據(jù)
本資源直接給出用java實(shí)現(xiàn)的從ts流中提取I幀的代碼
代碼片段和文件信息
/**
?*?從ts字節(jié)流中提取出I幀數(shù)據(jù),且去掉其中的音頻數(shù)據(jù),輸出的內(nèi)容仍然符合MPEG-2的188結(jié)構(gòu)
?*?@param?src:ts數(shù)據(jù)字節(jié)內(nèi)容
?*?@param?pos:提取I幀的起始位置,即從ts數(shù)據(jù)字節(jié)內(nèi)容的什么位置開始提取,默認(rèn)給0即可
?*?@param?audioPid:ts數(shù)據(jù)中音頻的pid,以便去掉音頻數(shù)據(jù),否則推送I幀數(shù)據(jù)時(shí)會(huì)聽到異常的聲音
?*?@return:符合MPEG-2的188數(shù)據(jù)封裝結(jié)構(gòu)的I幀數(shù)據(jù)(可能是多個(gè)I幀數(shù)據(jù))可以直接把返回內(nèi)容寫到文件,用vlc播放看到效果
?*/
public?static?byte[]?getiframes(byte[]?srcint?posint?audioPid){
List?list?=?new?linkedList();
int?start?=?0;
int?idx?=?0;
idx?=?pos;
boolean?iframe?=?false;
int?offset?=?0;
int?suffix?=?0;
int?totalLen?=?0;
while(idx?(src.length-6)){
if(src[idx]==0x0?&&?src[idx+1]==0x0&&src[idx+2]==0x01?&&?src[idx+3]==0x00){
if(((src[idx+5]>>3)&0x07)==0x01){
if(!iframe){
start?=?idx;
iframe?=?true;
}
else{
if(idx>start){
offset?=?start%188;
suffix?=?188-(idx%188);
byte[]?buff?=?new?byte[idx+offset+suffix-start];
System.arraycopy(src?start-offset?buff?0?idx+offset+suffix-start);
totalLen?+=?buff.length;
list.add(buff);
}
start?=?idx+suffix;
評(píng)論
共有 條評(píng)論