flv格式中有很多tag标签,合并flv视频不仅把视频文件和在一起,而且要修改duration值和每个tag的时间戳,代码如下

头文件type.h
#ifndef _TYPE_H_
#define _TYPE_H_
//flv文件头
struct FLVHeader
{
//标志
unsigned char signature_1;
unsigned char signature_2;
unsigned char signature_3;
unsigned char version;//版本
unsigned char typeflag; //类型标识
unsigned int dataoffset;//头的长度
};
//flv文件tag
struct FLVTag
{
unsigned char reserved2_filer1_tagtype5;
unsigned char datasize[3];//信息长度
unsigned char timestamp[3];//时间戳
unsigned char timestampextended;//时间戳的扩展
unsigned char streamid[3];//通常是0
//...
};
#endif
源文件flvbind.cpp
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "type.h"
using namespace std;
#define  _CRT_SECURE_NO_WARNINGS
unsigned int BigEndiantoLittleEndian32(unsigned char *num)
{
unsigned int nResult=0;
nResult=num[0]<<24 | num[1]<<16 | num[2]<<8 | num[3];
return nResult;
}
//获得flv视频播放时间
unsigned int* GetFlvTime(FILE *pFile)
{
bool isVideo=false;
bool isAudio=false;
unsigned int* time=(unsigned int*)malloc(sizeof(unsigned int)*2);
time[0]=0;
time[1]=0;
unsigned char presize[4];
FLVTag tag={0};
//FILE *pFile=fopen(name,"r"); //打开flv文件
if(pFile==NULL)
{
printf("文件不存在!");
return NULL;
}
else
{
fseek(pFile,0,SEEK_END);
long pos;
unsigned int size;
pos=ftell(pFile);
fseek(pFile,pos-4,SEEK_SET);
while(true)
{
pos=ftell(pFile);
fread(presize,4,1,pFile);
size=BigEndiantoLittleEndian32(presize);
fseek(pFile,pos-size,SEEK_SET);
pos=ftell(pFile);
fread(&tag,sizeof(FLVTag),1,pFile);
unsigned char tagtype=tag.reserved2_filer1_tagtype5 & 0x1f;
if(tagtype ==9)
{
time[0]=tag.timestamp[0] << 16 | tag.timestamp[1] <<8 | tag.timestamp[2];
isVideo=true;
if(isAudio)
break;
}
if(tagtype==8)
{
time[1]=tag.timestamp[0] << 16 | tag.timestamp[1] <<8 | tag.timestamp[2] ;
isAudio=true;
if(isVideo)
break;
}
fseek(pFile,pos-4,SEEK_SET);
}
//fclose(pFile);
}
return time;
}
//改变每个video后audio tag的时间戳
void ChangeTimeStampAndWrite(unsigned int &videosum,unsigned int &audiosum,FILE *pDest,FILE *pSource)
{
fseek(pSource,0,SEEK_END);
unsigned int endpos=ftell(pSource);
rewind(pSource);
fseek(pSource,13,SEEK_SET); //跳过flv文件头
unsigned int pos=ftell(pSource);
FLVTag tag={0};
unsigned char tagtype;
unsigned int datasize=0;
int video_sum=0;
int audio_sum=0;
while(true)
{
fread(&tag,sizeof(FLVTag),1,pSource);
tagtype=tag.reserved2_filer1_tagtype5 & 0x1f;
if(tagtype==18)  //script data
{
//do nothing
}
else if(tagtype==9) //video
{
video_sum=videosum+(tag.timestamp[0]<<16 | tag.timestamp[1]<<8 | tag.timestamp[2]);
tag.timestamp[0]=(unsigned char)((video_sum & 0x00ff0000)>>16);
tag.timestamp[1]=(unsigned char)((video_sum & 0x0000ff00)>>8);
tag.timestamp[2]=(unsigned char)((video_sum & 0x000000ff));
fwrite(&tag,sizeof(FLVTag),1,pDest);
}
else//audio
{
audio_sum=audiosum+(tag.timestamp[0]<<16 | tag.timestamp[1]<<8 | tag.timestamp[2]);
tag.timestamp[0]=(unsigned char)((audio_sum & 0x00ff0000)>>16);
tag.timestamp[1]=(unsigned char)((audio_sum & 0x0000ff00)>>8);
tag.timestamp[2]=(unsigned char)((audio_sum & 0x000000ff));
fwrite(&tag,sizeof(FLVTag),1,pDest);
}
datasize=tag.datasize[0]<<16 | tag.datasize[1]<<8 | tag.datasize[2];
pos+=datasize+11+4;
if(tagtype!=18)
{
unsigned int size=datasize+15-sizeof(FLVTag);
char *other=(char*)malloc(size);
fread(other,size,1,pSource);
fwrite(other,size,1,pDest);
free(other);
}if(pos>=endpos)
{
break;
}
fseek(pSource,pos,SEEK_SET);
}
}
//无符号16位整数的大端格式转小端
unsigned short BigToLittleUI16(unsigned short n)
{
unsigned short result;
result=((n & 0xff00)>>8) | ((n & 0x00ff)<<8);
return result;
}
//无符号32位整数的大端格式转小端
unsigned int BigToLittleUI32(unsigned int n)
{
unsigned int result;
result=((n & 0xff000000)>>24) | ((n & 0x00ff0000)>>8) | ((n & 0x0000ff00)<<8) | ((n & 0x000000ff)<<24);
return result;
}
//修改duration的值
void ResetDuration(FILE *file,long double newduration)
{unsigned char *p=(unsigned char*)&newduration;
//小端格式转大端格式
for(int i=0;i<4;i++)
{
unsigned char temp;
temp=p[i];
p[i]=p[7-i];
p[7-i]=temp;
}
fseek(file,13,SEEK_SET);
FLVTag flvtag;
//读取onMetadata信息
fread(&flvtag,sizeof(FLVTag),1,file);
if((flvtag.reserved2_filer1_tagtype5 & 0x1f)!=18)
{
return ;
}
fseek(file,24,SEEK_SET);
unsigned char type;
int len=0;
fread(&type,1,1,file);
unsigned short strsize;
fread(&strsize,2,1,file);
strsize=BigToLittleUI16(strsize);
long pos=ftell(file);
fseek(file,pos+strsize,SEEK_SET);
fread(&type,1,1,file);
unsigned int size;
fread(&size,4,1,file);
size=BigToLittleUI32(size);
char *str;
//遍历onMetaData数组
for(unsigned int i=1;i<=size;i++)
{
fread(&strsize,2,1,file);
strsize=BigToLittleUI16(strsize);
str=(char*)malloc(strsize+1);
str[strsize]=0;
fread(str,strsize,1,file);
//找到duration项修改播放时间
if(strcmp(str,"duration")==0)
{
unsigned char ui8;
fread(&ui8,1,1,file);
long double temp;
pos=ftell(file);
fread(&temp,8,1,file);
fseek(file,pos,SEEK_SET);
//修改duration的值
fwrite(&newduration,8,1,file);
break;
}
else
{
fread(&type,1,1,file);
pos=ftell(file);
if(type==0) //double
{
fseek(file,pos+8,SEEK_SET);
}
else if(type==1) //boolean
{
fseek(file,pos+1,SEEK_SET);
}
else if(type==2) //scriptdatastring
{
fread(&strsize,2,1,file);
pos=ftell(file);
strsize=BigToLittleUI16(strsize);
fseek(file,pos+strsize,SEEK_SET);
}
else
{
break;
}
}
//释放资源
free(str);
}
}int main(int argc,char **argv)
{
FILE *pDest;
FILE *pFirst;
FILE *pOthers;
if(argc<3)
{
printf("格式为:flvbind 目标文件名 源文件名 源文件名...");
}
else
{
printf("正在合并,请稍后...\n");
//若目标文件存在则清空
pDest=fopen(argv[1],"w+");
fclose(pDest);
pDest=fopen(argv[1],"ab+");
pFirst=fopen(argv[2],"rb+");
unsigned int videosum=0,audiosum=0;
unsigned int *time=GetFlvTime(pFirst);
videosum=time[0];
audiosum=time[1];
fseek(pFirst,0,SEEK_END);
unsigned int size=ftell(pFirst);
rewind(pFirst);
unsigned char *data=(unsigned char*)malloc(size);
memset(data,0,size);
fread(data,size,1,pFirst);
fwrite(data,size,1,pDest);
free(data);
fclose(pFirst);
//按参数遍历所有视频源文件(除第一个源文件)
for(int i=3;i<argc;i++)
{
pOthers=fopen(argv[i],"rb+");
ChangeTimeStampAndWrite(videosum,audiosum,pDest,pOthers);
time=GetFlvTime(pOthers);
videosum+=time[0];
audiosum+=time[1];
fclose(pOthers);
}
free(time);
fclose(pDest);
pDest=fopen("d:\\a.flv","rb+");
//获得总时间
long double duration=(long double)(videosum)/1000;
//重设duration的值
ResetDuration(pDest,duration);
fclose(pDest);
printf("OK\n");
}
return 0;
}

flv视频合并(vs2008)相关推荐

  1. 最好的FLV视频下载器 维棠 (支持优酷视频下载、土豆视频下载等)

    维棠FLV视频下载能帮助你轻松下载国内外大多数FLV视频分享网站的视频内容;并且维棠FLV视频下载具有断点续传功能. 现在国内外出现了很多视频分享网站,每个用户都可以把自己的视频节目和其他人分享.这些 ...

  2. 视频合并软件怎么把多个视频合并为一个视频

    视频合并软件怎么把多个视频合并为一个视频.经常操作视频编辑的小伙伴对视频合并是再熟悉不过的了,一般制作视频前的拍摄工作都是在多个场景中拍摄多个片段,通过后期剪辑将拍摄的多个视频片段合并到一起.而对于视 ...

  3. flv视频怎么转换成mp4格式的3种方法分享

    flv视频怎么转换成mp4格式?因为flv视频格式我们使用的很少,兼容性也不如mp4.虽然flv视频文件体积小:便于传输.共享:但是flv视频质量不好:不被所有播放器支持.flv视频格式是一种新的视频 ...

  4. 一款绿色免费的FLV文件合并裁剪器

    软件名称:花园FLV文件合并裁剪器 软件版本:1.0版 文件大小:452KB 授权形式:免费软件 应用平台:Windows 98/Windows 2000/Windows XP/VISTA/Windo ...

  5. 视频合并器(Video Combiner)绿色免费版 v1.1

    视频合并器是一款非常好用的视频合并软件,它的英文名叫做Video Combiner,体积小巧,占用内存空间小,运行速度快,功能强大,可以一次性将多个视频格式文件合并成一个单独的视频文件,并且有多种自适 ...

  6. Video Combiner(视频合并器) v1.1绿色免费版

    Video Combiner是一款Windows平台下的全格式视频合并工具软件,它可以一次性将多个视频格式文件合并成一个单独的视频文件,并且有多种自适应屏幕尺寸可以选择. 这款合并器支持苹果iPhon ...

  7. 可以同时合并不同尺寸不同格式视频的视频合并工具

    现在各种小视频很火,不少朋友也需要合并自己录制的和获取的视频文件.视频文件格式很多,而且经常尺寸不一,是否有一个办法可以无论什么格式.什么尺寸的视频都可以合并呢?这里我就分享一个好用的视频合并工具软件 ...

  8. Java使用ffmpeg进行视频格式转换、音视频合并、播放、截图

    封装类: ffplay.ffmpeg.ffprobe是安装的ffmpeg路径. import java.io.BufferedReader; import java.io.File; import j ...

  9. php把视频合成画中画,视频画面合并软件-怎么把多个视频合并到一个视频画面里面,制作多画面视频播放效果...

    视频画面合并软件-怎么把多个视频合并到一个视频画面里面,制作多画面视频播放效果 平时我们在网上经常可以看到很多视频同一个视频画面带有很多个不同的视频在同时播放,这是怎么做到的呢?这个也叫视频画中画,用 ...

  10. linux下视频格式转换与视频合并

    熟悉Windows的朋友应该知道,Windows下的视频格式转换软件与合并视频软件不计其数,刚接触Linux的朋友也许会抱怨Linux下没有强大的视频软件,完成视频播放.转化视频格式.合并视频等功能. ...

最新文章

  1. Bootstrap fileinput.js,最好用的文件上传组件
  2. OpenCV:OpenCV中的 parallel_for 和opencv parallel_for_
  3. SAP Spartacus 中的 HTML 标签
  4. 【JEECG技术文档】数据权限自定义SQL表达式用法说明
  5. 鸿蒙渊之后是什么任务,都说这次主线好,那我来唱唱反调吧
  6. ICLR 2021 | 腾讯 AI Lab 入选论文
  7. 关于@Alias注解的几个问题
  8. 【codevs1722】【NOI1997】最优乘车,单元最短路?
  9. 【自】数据库系统原理(三)——测试总结后,
  10. Android图形显示系统——下层显示1:基础知识与相关文件
  11. python坐标系教程_python Shapely使用指南详解
  12. FPGrowth算法理论
  13. 紫乌鸦服务器维护后多久刷,魔兽世界紫乌鸦怎么刷 刷新点在哪什么时候去蹲点...
  14. Ubuntu修改Mac地址
  15. rand()和srand()
  16. 手撸JDK之ReentrantLock锁那点事
  17. 输入一个角度的弧度值x,计算该角的余弦值
  18. 镜像网络MW受邀亮相巴比特杭州区块链国际周
  19. 智能化场景识别,8个视频图像处理方案你值得拥有
  20. 3、InnoDB存储引擎

热门文章

  1. html光标自动定位到文本框,进入JSP页面时就将光标定位到指定的文本框中
  2. Notepad++设置记录
  3. 软件工程毕业设计课题(80)微信小程序毕业设计PHP电影视频播放小程序系统设计与实现
  4. excel高级筛选怎么用_Excel高级筛选教程(完整版)-第二期注入灵魂的条件区域
  5. 1167. Anagrammatic Distanc (字符串匹配)
  6. Adobe ColdFusion
  7. coldfusion_ColdFusion MX 7功能之旅
  8. YOLOX: Exceeding YOLO Series in 2021 论文阅读笔记
  9. OpenCV黑魔法之隐身衣 | 附源码
  10. 任天堂游戏 html5,任天堂Switch游戏销量排行Top40,赶快收藏跟着买就对啦!