首先在阅读本代码之前百度一下avi,虽然经过我验证上面有部分错误,但是不影响阅读。因为有些变量的注释我没有写,所以请读者自行搜索吧。下面是c语言文件,编译之后能够直接运行,用来截取开始时间(单位s)后指定长度(单位s)的视频流。最后附上一部分视频文件的二进制,方便对照阅读。

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

#include <fcntl.h>

#include <string.h>

#pragma pack(1)

/*

最开始的4个字节是一个四字符码‘RIFF’,表示这是一个RIFF文件;紧跟着后面用4个字节表示此RIFF文件的大小;

然后又是一个四字符码说明文件的具体类型(比如AVI、WAVE等);最后就是实际的数据。注意文件大小值的计算

方法为:实际数据长度 +4(文件类型域的大小);也就是说,文件大小的值不包括‘RIFF’域和“文件大小”域本身

的大小。

*/

typedef struct RIFF

{

char riff[4];

unsigned int size;

char type[4];

}RIFF;

/*

注意listSize值的计算方法为:实际的列表数据长度 +4(listType域的大小);也就是说listSize值不包括‘LIST’域和listSize域本身的大小。

*/

typedef struct list

{

char fcc[4];

unsigned int size;

char type[4];

}LIST;

/*************avih*********************/

typedef struct _avimainheader

{

char fcc[4];//'avih'

int size;// 本数据结构的大小,不包括最初的8个字节(fcc和cb两个域)

int dwMicroSecPerFrame;//视频帧间隔时间(以微秒为单位)

int dwMaxBytesPerSec;// 这个AVI文件的最大数据率

int dwPaddingGranularity;// 数据填充的粒度

int dwFlags;// AVI文件的全局标记,比如是否含有索引块等

int dwTotalFrames; // 总帧数

int dwInitialFrames; // 为交互格式指定初始帧数(非交互格式应该指定为0)

int dwStreams;// 本文件包含的流的个数

int dwSuggestedBufferSize; // 建议读取本文件的缓存大小(应能容纳最大的块)

int dwWidth;//视频图像的宽(以像素为单位)

int dwHeight;//视频图像的高(以像素为单位)

int dwReserved[4]; // 保留

}AVIMAINHEADER;

/********strh*******/

typedef struct

{

short int left;

short int top;

short int right;

short int bottom;

}RCFRAME;

typedef struct _avistreamheader

{

char fcc[4];// 必须为‘strh’

int size;

char fccType[4];// 流的类型:‘auds’(音频流)、‘vids’(视频流)、

char fccHandler[4];// 指定流的处理者,对于音视频来说就是解码器

int  dwFlags;// 标记:是否允许这个流输出?调色板是否变化?

int wPriority;// 流的优先级(当有多个相同类型的流时优先级最高的为默认流)

int wLanguage;

int dwInitialFrames; // 为交互格式指定初始帧数

int dwScale;// 这个流使用的时间尺度

int dwRate;

int dwStart;// 流的开始时间

int dwLength;// 流的长度(单位与dwScale和dwRate的定义有关)

int dwQuality;// 流数据的质量指标(0 ~ 10,000)

int dwSampleSize;// Sample的大小

RCFRAME rcFrame;// 指定这个流(视频流或文字流)在视频主窗口中的显示位置

}AVISTREAMHEADER;

/**************strf_vids********************/

typedef struct tagBITMAPINFOHEADER

{

char fcc[4];

int biSize;

int biWidth;

int biHeight;

short int biPlanes;

short int biBitCount;

int biCompression;

int biSizeImage;

int biXPelsPerMeter;

int biYPelsPerMeter;

int biClrUsed;

int biClrImportant;

}BITMAPINFOHEADER;

typedef struct tagBITMAPINFO

{

BITMAPINFOHEADER bmiHeader;

int  bimColors[1];

}BITMAPINFO;

/***************strf_auds*********************/

//#define WAVEFORMAT __attribute__((packed))

typedef struct

{

char fcc[4];

int size;

short int wFormatTag;

short int nChannels;

int nSamplesPerSec;

int nAvgBytesPerSec;

short int nBlockAlign;

short int wBitsPerSample;

short int biSize;

}WAVEFORMAT;

typedef struct strl_vids

{

LIST list;

AVISTREAMHEADER strh;

BITMAPINFO strf;

}STRL_VIDS;

typedef struct strl_auds

{

LIST list;

AVISTREAMHEADER strh;

WAVEFORMAT strf;

}STRL_AUDS;

typedef struct junk

{

char fcc[4];

int size;

}JUNK;

typedef struct HDRL

{

AVIMAINHEADER avih;

STRL_VIDS strl_vids;

STRL_AUDS strl_auds;

JUNK junk;

}HDRL;

typedef struct movi

{

char id[4];

int length;

}MOVI;

typedef struct data

{

LIST list;

MOVI chunk;

}DATA;

typedef struct aindex

{

char dwChunkId[4];

int dwFlags;

int dwOffset;

int dwSize;

}AINDEX;

typedef struct avi_idxl

{

char fcc[4];

AINDEX aindex[10];

}AVI_IDXL;

void print_avihead(RIFF riff,LIST list,HDRL hdrl)

{

printf("riff.size=%d\n",riff.size);

printf("list.size=%d\n",list.size);

printf("hdrl.avih.fcc=%s\n",hdrl.avih.fcc);

printf("hdrl.avih.dwTotalFrames=%d\n",hdrl.avih.dwTotalFrames);

printf("hdrl.avih.dwMicroSecPerFrame=%dms\n",hdrl.avih.dwMicroSecPerFrame/1000);

printf("hdrl.strl_vids.strh.fcc=%s\n",hdrl.strl_vids.strh.fcc);

printf("hdrl.strl_auds.strh.fcc=%s\n",hdrl.strl_auds.strh.fcc);

printf("hdrl.junk.fcc=%c\n",hdrl.junk.fcc[3]);

printf("hdrl.junk.size=%d\n",hdrl.junk.size);

}

void get_aviidxl(AVI_IDXL*idxl,char*src_buf,int off_set)

{

char*p;

p=src_buf+off_set;

memcpy(idxl,p,sizeof(AVI_IDXL));

printf("idxl.fcc:%s\n",idxl->fcc);

}

long get_file_size(const char *path)

{

unsigned long filesize = -1;

FILE*fp;

fp = fopen(path,"r");

if(fp==NULL)

{

return filesize;

}

fseek(fp,0,SEEK_END);

filesize = ftell(fp);

fclose(fp);

return filesize;

}

int main(int argc ,char*argv[])

{

unsigned long size;

int count=0,i;

int begin_s=60;//开始时间s

int t_s=20;//截取间隔s

int fd_src,fd_dst;

int off_set;

char*buf,*readbuf;

char*src_buf,*tmp;

RIFF riff;

LIST lhdrl;

HDRL hdrl;

LIST lmovi;

MOVI movi;

/*******************打开源文件与目的文件*****************************/

fd_src = open("H264.avi",O_RDONLY);

fd_dst = open("out.avi",O_CREAT|O_RDWR,0777);

/************将源文件内容读入缓存区***********************/

lseek(fd_src,0,SEEK_SET);

read(fd_src,&riff,sizeof(riff));

read(fd_src,&lhdrl,sizeof(lhdrl));

read(fd_src,&hdrl,lhdrl.size+4);

//    print_avihead(riff,lhdrl,hdrl);

/*********建立JUNK缓存区存储0************/

buf=malloc(hdrl.junk.size);

memset(buf,0,hdrl.junk.size);

/**********将文件头与JUNK区写入目标文件***********/

lseek(fd_dst,sizeof(riff),SEEK_CUR);

lseek(fd_dst,sizeof(lhdrl),SEEK_CUR);

lseek(fd_dst,sizeof(hdrl),SEEK_CUR);

//write(fd_dst,&riff,sizeof(riff));

//write(fd_dst,&list,sizeof(list));

//write(fd_dst,&hdrl,sizeof(hdrl));

write(fd_dst,buf,hdrl.junk.size);

free(buf);

/***********偏移至movi区获取实际数据***************/

lseek(fd_src,hdrl.junk.size,SEEK_CUR);

read(fd_src,&lmovi,sizeof(lmovi));

write(fd_dst,&lmovi,sizeof(lmovi));

/******写数据*****/

while(1)//for(i =0 ;i < 20;i++)

{

read(fd_src,&movi,sizeof(movi));

if(movi.length%2!=0)

{

movi.length+=1;

}

buf = malloc(movi.length);

read(fd_src,buf,movi.length);

//         printf("%d\tmovi.id=%s\n",count,movi.id);

if(((strncmp(movi.id+2,"db",2)==0)||(strncmp(movi.id+2,"dc",2)==0))&&(count<begin_s*25))//25帧是1秒

{

free(buf);

count++;

//    printf("%d\tmovi.id=%s\n",count,movi.id);

continue;

}

if(((strncmp(movi.id+2,"pc",2)==0)||(strncmp(movi.id+2,"wb",2)==0))&&((count-1)<begin_s*25))//音频帧不计算在内,时间只用视频帧计算

{

free(buf);

continue;

}

if(((strncmp(movi.id+2,"db",2)==0)||(strncmp(movi.id+2,"dc",2)==0))&&(count>=begin_s*25))

{

count++;

printf("%d\tmovi.id=%s\tmovi.size=%x\n",count,movi.id,movi.length);

}

write(fd_dst,&movi,sizeof(movi));

write(fd_dst,buf,movi.length);

size=size+movi.length+8;

free(buf);

if(count>(begin_s+t_s)*25)

{

break;

}

//free(buf);

//size=size+movi.length+8;

}

riff.size=12+12+lhdrl.size+4+hdrl.junk.size+12+size;//计算数据大小,用来填充报头

hdrl.avih.dwTotalFrames=count;//大小字节

lseek(fd_dst,0,SEEK_SET);

write(fd_dst,&riff,sizeof(riff));

write(fd_dst,&lhdrl,sizeof(lhdrl));

write(fd_dst,&hdrl,sizeof(hdrl));

//    off_set=off_set+8+data.list.size;

//    get_aviidxl(&idxl,src_buf,off_set);

//    write(fd_dst,src_buf,size);

close(fd_src);

close(fd_dst);

}

报头的图片

中间是JUNK的填充

这是一部分数据,都不到一帧,所以最好自己找个avi文件对照的我的代码看。
————————————————
版权声明:本文为CSDN博主「天晓-workspace」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38697824/article/details/85341049

截取AVI格式的视频C语言代码相关推荐

  1. AVI音视频封装格式学习(四)——linux系统C语言AVI格式音视频封装应用

    拖了很久的AVI音视频封装实例,花了一天时间终于调完了,兼容性不是太好,但作为参考学习使用应该没有问题.RIFF和AVI以及WAV格式,可以参考前面的一些文章.这里详细介绍将一个H264视频流和一个2 ...

  2. IjkVideoView播放视频(支持avi格式的视频)

    上一篇   Ijkplayer播放视频(支持AVI格式的视频) 讲了,Ijkplayer和SurfaceView结合,播放视频.这一篇我们把Ijkpayer和SurfaceView进行封装,封装成Ij ...

  3. Qt实现avi格式录制视频

    声明:刚刚接触qt开发,觉得qt真的很强大,也正是因为它的强大,所以在这条路上还有很远很远的路要走,希望大家多多指教,多多交流共同进步.另外由于本人不是系统的从头开始学qt,主要是在实战需求中来实现功 ...

  4. 怎么把avi格式的视频转换成gif动态图

    随着gif动态图越来越火爆,制作gif动态图的小伙伴也越来越多,在制作gif时我们经常会在互联网下载视频作为制作素材,而下载的诸多视频格式中avi格式作为流行的视频格式被大量下载.那怎么用迅捷视频转换 ...

  5. 如何使用JiaoZiVideoPlayer(饺子视频播放器)播放avi格式的视频

    如何使用JiaoZiVideoPlayer(饺子视频播放器)播放avi等原生不支持的格式的视频 1.为什么使用JiaoZiVideoPlayer播放AVI格式的视频 有的同学可能会发现,部分.avi文 ...

  6. 如何将AVI格式的视频转换为MP4?用嗨格式试试看

    如何将AVI格式的视频转换为MP4?MP4是目前最为常见且兼容性好的视频格式之一,但有时候遇到的视频格式是AVI的,怎么才能将其转换器MP4格式呢?下面就给你分享一个好用的方法. 首先在电脑上下载并运 ...

  7. MATLAB实现将图片转化为avi格式的视频

    MATLAB实现将图片转化为avi格式的视频   视频就是将一系列连续的图片进行播放的效果.所以将图片转换为AVI格式的视频就是将一系列连续的图片保存到AVI格式的文件中. 转换的通用格式: %% 保 ...

  8. android flv格式的视频文件,android-如何运行mkv,flv,avi格式的视频文件?

    我正在制作一个项目,使用使用videoview的简单代码,我可以播放3gp amd mp4格式的视频文件 vv = (VideoView) findViewById(R.id.videoView); ...

  9. html embed页面无法播放视频播放,用embed标签在网页中嵌入avi格式的视频不能播放...

    制作HTML网页插入视频Mp 4格式可以播放,AVI格式不可以播放的原因是因为引入的参数错误,如下正确的使用方式: objecthttp://activex.microsoft.com/activex ...

最新文章

  1. K-Means算法理论及Python实现
  2. java 与c 运行效率_Java语言与C语言代码运行效率的比较
  3. 柯泰测试同步采集软件,上海近场测试设备_柯泰测试
  4. Vue.js 相关知识(动画)
  5. matlab robotics工具箱(3)逆运动学
  6. 判断用户用手机访问还是用电脑访问网页
  7. canvas 擦除动画_帧动画的多种实现方式与性能对比
  8. Mp3Play.ocx控件让音乐之声响起来
  9. atexit函数详解
  10. android mac 调试,Mac下使用Android studio真机调试
  11. 快来看!我把小时候最喜欢的连连看游戏源代码拿来了~
  12. QGIS数据分析入门——Qgis下载及界面介绍(一)
  13. Metasploit之——基本后渗透命令
  14. 分析功能强大的蛋白质结构预测软件Phyre2
  15. 取决于数学符号_科学发现的未来取决于开放
  16. 汽车之家APP车型口碑--参数分析
  17. word表格怎么缩小上下间距_word表格怎么调整行高间距拉不动
  18. 一行代码实现shell if else逻辑
  19. java 时间字符串比较大小_java中如何比较两个时间字符串的大小
  20. PSGAN(2019SIGIR)

热门文章

  1. react 项目总结
  2. hdu 1161 Eddy's mistakes
  3. DiscoveryService.getRemoteAdvertisements是否会获得本地通告?
  4. 配置SAMBA文件共享的基本方法
  5. 石头机器人红灯快闪_机器人集体“快闪”活动爆红网络 “我是AI”与您相约智能新时代...
  6. python 内置模块 subprocess
  7. Docker 精通之微服务
  8. html中怎么写多选框,如何在HTML中实现“选择所有”复选框?
  9. loading gif 透明_搞笑GIF:有这样的女朋友下班哪里都不想去
  10. 【教程分享】Jmeter入门教程