Linux ffmpeg视频截图,C中操作JSON数据

来源:互联网 发布:unity php 编辑:程序博客网 时间:2024/06/16 14:26

Linux ffmpeg视频截图,C中操作JSON数据

ffmpeg 视频截图

上一篇介绍了ffmpeg 的安装, 这里介绍一下如何利用ffmpeg来创建视频缩略图。

ffmpeg参数较多,这里仅仅使用其中的几个,来完成创建视频截图的目的。

ffmpeg -ss 00:00:10 -i sample.mp4  -y -f image2 -t 0.001 -s 300x170 sample_out.jpg
参数 含义 -ss 指定ffmpeg的搜索时间点 -i 指定输入的文件 -y 覆盖输出 -f 指定采用的格式 -t 设置记录的时间 -s 设置帧大小

需要注意的是-ss参数,把它放在-i之前,命令执行的时间更快些,这个很多网上的资料都有介绍:如果放在后面的话,ffmpeg会先读入视频然后逐步搜索到指定的时间,故花费时间较久,而-ss放在前面时,ffmpeg则会直接跳到指定时间。


ffmpeg截图视频缩略图

得到的视频截图

如果要在C程序中执行这条命令,可以考虑使用execvp()函数, 或者popen和system函数。

下面的代码片段使用了execvp来执行该命令(留意execvp的参数),

char command[BUFSIZ] = "ffmpeg -ss 00:00:10 -i sample.mp4  -y -f image2 -t 0.001 -s 300x170 sample_out.jpg";//to cut the cwd by " " char delims[] = " ";int argc = 1;int i = 1;char **argvtmp;strcpy(argv[0],strtok(command,delims));while(p = strtok(NULL,delims)){    strcpy(argv[i++],p);    argc++;}//whileargvtmp = malloc(sizeof(char *)*argc+1);int j;for(j = 0;j < argc + 1;j++){    argvtmp[j] = malloc(sizeof(char)*100);    if(j < argc)       strcpy(argvtmp[j],argv[j]);  }//forargvtmp[argc] = NULL; if(execvp(argvtmp[0],argvtmp) < 0){        #ifdef DEBUG            printf("create video thumb failed!\n");                #endif  }

在C中操作JSON数据

这部分似乎和上一部分完全没关系,主要是因为自己项目的需要:使用json来传输视频的一些信息,其中包含视频的缩略图,因此就把这两部分放到一篇博客啦。

JSON是一种数据交换格式,全称是JavaScript Object Notation。这种格式中,要表示的东西被当做对象,对象由键值对(“item”:”value”)来表示,许多的对象可以构成一个数组。

{    "status":   1,    "data": [{            "name": "dubai.mp4",            "duration": "00:01:20.60",            "createTime":   "2017-5-9 13:34",        }, {            "name": "360test.mp4",            "duration": "00:00:42.63",            "createTime":   "2017-5-9 14:1",        }, {            "name": "panda.mp4",            "duration": "00:01:56.82",            "createTime":   "2017-5-9 14:1",        }],    "msg":  "SUCCESS"}

比如上面这段JSON数据中,有一个”data”数组([]括起来的部分),其中有三个对象({}括起来的部分),每个对象有三个键值对。


要想在C中操作JSON数据,需要使用到cJSON,不过一般我们只需要两个文件即可cJSON.c 和cJSON.h。
可以在这里找到简单的使用介绍JSON的简单介绍以及C语言的JSON库使用


以本项目的为例,

    char *video_json;    FILE *fp_json = fopen(video_list_json_path,"r+");    //video_list_json_path为原有JSON文件的位置    if(fp_json == NULL){        printf("open json file failed!\n");         }    fseek(fp_json,0,SEEK_END);    int fp_json_length = ftell(fp_json);    #ifdef DEBUG    printf("===length %d\n",fp_json_length);    #endif    video_json = (char*)malloc((fp_json_length+1) * sizeof(char));    fseek(fp_json,0,SEEK_SET);    fread(video_json,fp_json_length,sizeof(char),fp_json);    video_json[fp_json_length] = '\0';    cJSON *json = cJSON_Parse(video_json);    cJSON *array = NULL;    array = cJSON_GetObjectItem(json,"data");    cJSON *obj = NULL;    cJSON_AddItemToArray(array,obj = cJSON_CreateObject());    cJSON_AddStringToObject(obj,"name",video_info.video_name);    //video_info为视频信息的结构体,下同        cJSON_AddStringToObject(obj,"videoThumb",video_info.video_thumb_url);    cJSON_AddStringToObject(obj,"duration",video_info.video_duration);    cJSON_AddStringToObject(obj,"createTime",video_info.video_update_time);    cJSON_AddStringToObject(obj,"path",video_info.video_url);    FILE *fp_json_new = fopen(video_list_json_path_tmp,"w");        char *tmp_buf = cJSON_Print(json);    fwrite(tmp_buf,strlen(tmp_buf),1,fp_json_new);          //clean    cJSON_Delete(json);    fclose(fp_json);    fclose(fp_json_new);    remove(video_list_json_path);    rename(video_list_json_path_tmp,video_list_json_path);

其中关键的函数为:

函数原型 含义 cJSON *cJSON_Parse(const char *value) 解析JSON数据并返回cJSON结构 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) 获取JSON对象 void cJSON_AddItemToArray(cJSON *array, cJSON *item) 向数组中添加对象 cJSON_AddStringToObject(object,name,s) (宏函数)向对象中添加字符串作为键值

上面的代码片段的目的为:读取现有的JSON文件,向其中添加一个视频信息对象,达到更新JSON文件的目的。因为JSON文件是文本文件,有很清晰易读的组织结构,我们也可以自己去完成读取解析等工作,不过可能健壮性并没有cJSON写的这么好,所以,如果有需要的话,直接使用就好了。在其他的语言如JS,Python中,对JSON的支持会更友好一些,这里只是因为项目的需要而使用了C。


结果

将上述两部结合起来:创建的缩略图可以通过地址来访问,所以我们的JSON文件中需要有类似”video_capture”:”/picture/pitcture1.jpg”的键值对,用来保存每个视频的缩略图地址。

因项目还没结题,就不贴完整代码出来了。仅仅介绍一下整个的思路。编译时,一个可能的Makefile为:

#updateJsonCC = gccSRC1 = updateJson.cSRC2 = cJSON.c.PHONY : cleanall:    $(CC)  -g $(SRC1) $(SRC2) -o updateJson -lmclean:    -rm cJSON.o updateJson.o updateJson

一并编译cJSON.c,这个c文件需要链接数学库。

执行的结果如下:

原始JSON

更新后的JSON


Reference:
ffmpeg参数中文详细解释
JSON的简单介绍以及C语言的JSON库使用
ffmpeg命令截图范例参考
cJSON

0 0