TS流文件中提取I帧的方法

    ts流文件是MPEG-2的数字电视标准格式,目前使用最为广泛。
在一些视频服务中,如VOD推流的快进、快退中,经常需要快速从ts节目流中找出I帧(I-frame)来,以便推流服务器可以推送只包含视频画面而没有声音的ts数据到终端,而终端并不需要做任何特殊处理,即可实现快进/快退的画面效果。

因此,实现上需要做到以下三点:
1、要找到I帧
2、确保找出来的I帧数据前后都要完整,即符合MPEG-2的188长度的封包格式
3、去掉其中的音频数据

这样就可以把一个视频文件中的所有I帧提取出来,直接推送到终端,即可实现快进/快退的效果。
至于不同倍速的效果,则在推送已经提取出的I帧数据时,间隔不同I帧推送即可。

完整的算法如下:
(如果发现有问题或值得改进的地方,请留言,谢谢!)

public static byte[] getIframes(byte[] src,int pos,int 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 = start8;
suffix = 188-(idx8);
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;
iframe = true;
}
}
if (((((src[idx+5]>>3)&0x07)==0x02)||((src[idx+5]>>3)&0x07)==0x03)){
if (iframe){
offset = start8;
suffix = 188-(idx8);
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 = 0;
iframe = false;
}
}
idx++;
}
int audioLen = 0;
int pid = 0;
ByteBuffer buff = ByteBuffer.allocate(totalLen);
for (Iterator itr = list.iterator(); itr.hasNext();) {
byte[] bs = (byte[]) itr.next();
for (int i = 0; i < bs.length;) {
pid = ((bs[i+1] & 0x1F) << 8) + (bs[i + 2] & 0xFF);
if(pid==audioPid){
audioLen += 188;
}
else{
buff.put(bs,i,188);
}
i+=188;
}
bs = null;
}
ByteBuffer res = ByteBuffer.allocate(totalLen-audioLen);
res.put(buff.array(),0,totalLen-audioLen);
buff.clear();
list.clear();
list = null;
buff = null;
return res.array();
}
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值