1 Star 0 Fork 1

罗声海/vedio stream

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
tunc_flv.c 5.97 KB
一键复制 编辑 原始数据 按行查看 历史
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "flv.h"
const char *infile = "haige666.flv";
const char *outfile = "chunc.flv";
int ntoh24s(oal_uint24 * num)
{
int value = 0;
value += num->first<<16;
value += num->second<<8;
value += num->third;
//printf("the value is [%d]\n",value);
return value;
}
int oal_h2n_long(int num)
{
int num1 = 0;
int temp = 0;
for(int i = 0 ;i < 4; i++)
{
temp = num>>(i*8);
num1 += temp<<(32-(i+1)*8);
temp = 0;
}
return num1;
}
int oal_n2h_long(int num)
{
int num1 = 0;
int temp = 0;
for(int i = 0 ;i < 4; i++)
{
temp = num>>(i*8)&0xff;
num1 += temp<<(32-(i+1)*8);
temp = 0;
}
printf("num1 [%d] \n",num1);
return num1;
}
char * find_scipt_head(char *buffer,int len)
{
FLV_HEADER *flv_head = (FLV_HEADER *)buffer;
int head_len = oal_n2h_long(flv_head->offset);
printf("flv header length is [%d] \n",head_len);
if(len < head_len)
{
printf("the head len is wrong\n");
return NULL;
}
return (buffer + head_len);
}
char * find_vedio_head(char *script_head , int * script_len)
{
FLVTAG_HEADER *tag_head = (FLVTAG_HEADER *)script_head;
int datalen = ntoh24s(&(tag_head->data_len));
printf("the script type is [%d]\n",tag_head->tag_type);
printf("the scripttag data len is [%d]\n",datalen);
*script_len = datalen + 11;
printf("the script total len is [%d]\n",*script_len);
VEDIO_HEAD *vedio_header = (VEDIO_HEAD *)(tag_head + 1);
//printf("the frame type1 [%d]\n",vedio_header->frame_type);
printf("the frame type2 [%d]\n",vedio_header->stream_id);
AVC_HEAD *avc_header = (AVC_HEAD *)(vedio_header + 1);
printf("the avc type is [%d]\n\n",avc_header->avc_type);
return script_head + 15 + datalen;
}
char * find_next_vedio_head(char *last_data_head , int * tag_len , int *quit)
{
static int frame_count = 0;
FLVTAG_HEADER *tag_head = (FLVTAG_HEADER *)last_data_head;
int datalen = ntoh24s(&(tag_head->data_len));
//printf("the tag type is [%d]\n",tag_head->tag_type);
//printf("the vedio data len is [%d]\n",datalen);
*tag_len = datalen + 11;
//printf("the vedio total len is [%d]\n",*tag_len);
VEDIO_HEAD *vedio_header = (VEDIO_HEAD *)(tag_head + 1);
//printf("the frame type1 [%d]\n",vedio_header->frame_type);
//printf("the frame type2 [%d]\n",vedio_header->vedio_header);
AVC_HEAD *avc_header = (AVC_HEAD *)(vedio_header + 1);
//printf("the avc type is [%d]\n\n",avc_header->avc_type);
frame_count ++;
if( frame_count > 4 && vedio_header->stream_id == 1 )
{
printf("frame_count [%d]\n",frame_count);
*quit = 1;
}
return last_data_head + 15 + datalen;
}
int do_tunc(char *buffer , int buffer_len)
{
int meta_len = 0;
char *script_head = find_scipt_head(buffer,buffer_len);
if(script_head == NULL)
{
return -1;
}
int script_tag_len = 0;
char *vedio_data = find_vedio_head(script_head,&script_tag_len);
vedio_data = find_vedio_head(vedio_data,&script_tag_len);
printf("___________________________\n");
meta_len = vedio_data - buffer;
int tag_len;
int flag = 400;
char *next_vedio_tag = vedio_data;
//char *end_tag_head;
int quit = 0;
while(flag-- != 0)
{
char *last_tag = next_vedio_tag;
next_vedio_tag = find_next_vedio_head(next_vedio_tag,&tag_len , &quit);
if(quit)
{
//end_tag_head = next_vedio_tag;
//printf("break, the buffer [%p] , the end [%p]\n",buffer + buffer_len , next_vedio_tag);
next_vedio_tag = last_tag;
break;
}
}
//end_tag_head = next_vedio_tag;
//next_vedio_tag = vedio_data;
FLVTAG_HEADER *new_vedio_head = (FLVTAG_HEADER *)next_vedio_tag;
new_vedio_head->PreviousTagSize = oal_h2n_long(script_tag_len);
printf("script tag len is [%d]!\n",oal_n2h_long(new_vedio_head->PreviousTagSize));
int fd = open(outfile,O_CREAT|O_RDWR);
if(fd < 0)
{
printf("cnnot open out file!\n");
return -1;
}
int ret = 0;
int write_len = 0;
do
{
ret = write(fd,buffer + write_len ,meta_len - write_len);
write_len += ret;
}while(meta_len > write_len);
//int end_len = buffer_len - (end_tag_head - buffer);
int left_len = buffer_len - (next_vedio_tag - buffer);
write_len = 0;
int repeat = 1;
while(repeat -- > 0)
{
do
{
ret = write(fd,next_vedio_tag + write_len ,left_len - write_len);
write_len += ret;
} while (left_len > write_len);
write_len = 0;
printf("write !!!\n");
}
// write_len = 0;
// do
// {
// ret = write(fd,end_tag_head + write_len ,end_len - write_len);
// write_len += ret;
// } while (end_len > write_len);
close(fd);
printf("write ok!!!\n");
return 0;
}
int main()
{
FILE* fp;
char *p;
fp = fopen(infile,"rb");// localfile文件名
if(fp == NULL)
{
printf("the file is not exsit\n");
return -1;
}
fseek(fp,0L,SEEK_END); /* 定位到文件末尾 */
int flen = ftell(fp); /* 得到文件大小 */
//oal_print("the file len is [%u]\n",flen);
p = (char *)malloc(flen); /* 根据文件大小动态分配内存空间 */
if(p==NULL)
{
fclose(fp);
printf("malloc failed\n");
return -1;
}
fseek(fp,0L,SEEK_SET); /* 定位到文件开头 */
fread(p,1,flen,fp); /* 一次性读取全部文件内容 */
fclose(fp);
/*
函数名: fread
功 能: 从一个流中读数据
用 法: int fread(void *ptr, int size, int nitems, FILE *stream);
参 数:用于接收数据的地址(ptr)
单个元素的大小(size)
元素个数(nitems)
提供数据的文件指针(stream)
返回值:成功读取的元素个数
程序例:
*/
if(do_tunc(p,flen) < 0)
{
printf("do tunc failed\n");
}
free(p);
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/luo-shenghai/vedio-stream.git
git@gitee.com:luo-shenghai/vedio-stream.git
luo-shenghai
vedio-stream
vedio stream
master

搜索帮助