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

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++;
}//while

argvtmp = 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]);  
}//for
argvtmp[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为:

#updateJson
CC = gcc
SRC1 = updateJson.c
SRC2 = cJSON.c

.PHONY : clean

all:
    $(CC)  -g $(SRC1) $(SRC2) -o updateJson -lm
clean:
    -rm cJSON.o updateJson.o updateJson

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

执行的结果如下:

原始JSON

更新后的JSON


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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值