- 任务:在linux平台下多次调用ffmpeg来切割多个视频
- 思考与难点:既然需要多次调用命令行命令ffmpeg,自然而然想到需要写一个shell脚本在c++程序中调用这个脚本就行了,但是问题并没有这么简单。c++程序中如何调用shell脚本?该怎么向shell脚本传入参数呢?shell脚本又是怎样来接受参数的
1、c++程序中如何调用shell脚本?
三种方式各有千秋,考虑到我写脚本十分简单,所以我用第一种调用方式system()。
2、该怎么向shell脚本传入参数呢?
这里我介绍的system的方式,看过system函数有一个字符串类型的参数,这个字符串就是你需要执行的脚本文件加上你需要传进去的参数。例如:
string command = "./flower.sh parameter1 parameter2";
system(command);
./flower.sh 可执行的shell脚本 parameter1需要传入的第一个参数 parameter2需要传入的第二个参数。
这一步非常重要也很容易出错,command中每个子串需要用空格隔开,在你写自己程序的是时候需要用strcpy()、strcat() 等函数把空格还有你的命令加进去。
char command[200] = {0};
string file = "./flower.sh ";
strcpy(command,file.c_str());
//parameter1
string parameter1 = ptr->d_name;
parameter1 = parameter1 + " ";
strcat(command,parameter1.c_str());
//parameter2
string parameter2 = strtok(bufname,".");
parameter2 = "_CIDI_" + parameter2;
parameter2 = parameter2 + ".mp4";
parameter2 = parameter2 + " ";
strcat(command,parameter2.c_str());
//parameter3
string parameter3 = argv[3];
parameter3 = parameter3 + " ";
strcat(command,parameter3.c_str());
//parameter4
strcat(command,argv[4]);
cout<<"command:"<<command<<endl;
system(command);
command:./flower.sh 2019-04-08,14:00:00,15:00:00.h264 _CIDI_2019-04-08,14:00:00,15:00:00.mp4 00:00:02 00:00:10
上面的代码拼接出了我想用的command。
3、shell脚本接受参数
其实shell脚本接受参数的方式很简单
#!/bin/sh
echo "$1" #input file name
echo "$2" #output file name
echo "$3" #start time
echo "$4" #end time
用$1接受第一个参数,$2接受第二个参数,以此类推。需要注意的是shell脚本最多可以接受10个参数。
我用echo "$1"打印出第一个参数......
command:./flower.sh 2019-04-08,14:00:00,15:00:00.h264 _CIDI_2019-04-08,14:00:00,15:00:00.mp4 00:00:02 00:00:10
2019-04-08,14:00:00,15:00:00.h264
_CIDI_2019-04-08,14:00:00,15:00:00.mp4
00:00:02
00:00:10
在shell脚本中成功打印出我在c++代码中传入的四个参数。
4、来看看实战的效果把
遍历文件夹,切割合适的时间段的视频,并生成切割后的视频。
test.cpp文件
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<dirent.h>
using namespace std;
int main(int argc,char *argv[])
{
DIR *dir;
if((dir=opendir(argv[1]))==NULL)
return -1;
struct dirent *ptr;
while((ptr=readdir(dir)) != NULL)
{
if(ptr->d_type == DT_REG)
{
int file_length = strlen(ptr->d_name);
char buf[file_length+1] = {0};
char bufname[file_length+1] = {0};
strcpy(bufname,ptr->d_name);
strcpy(buf,ptr->d_name);
string day_time = strtok(buf,",");
string start_time = strtok(NULL,",");
string end_time = strtok(NULL,".");
cout<<"file_name:"<<ptr->d_name<<endl;
cout<<"This file day_time:"<<day_time<<endl;
cout<<"This file start_time:"<<start_time<<endl;
cout<<"This file end_time:"<<end_time<<endl;
if(day_time != argv[2])
continue;
if(argv[3] >= start_time && argv[3] <= end_time)
{
if(argv[4] >= start_time && argv[4] <= end_time)
{
char *start = argv[3];
*start++ = '0';
*start = '0';
cout<<"argv[3]:"<<argv[3]<<endl;
char *end = argv[4];
*end++ = '0';
*end = '0';
cout<<"argv[4]:"<<argv[4]<<endl;
cout<<"---------------------------------------"<<endl;
}
}
char command[200] = {0};
string file = "./flower.sh ";
strcpy(command,file.c_str());
//parameter1
string parameter1 = ptr->d_name;
parameter1 = parameter1 + " ";
strcat(command,parameter1.c_str());
//parameter2
string parameter2 = strtok(bufname,".");
parameter2 = "_CIDI_" + parameter2;
parameter2 = parameter2 + ".mp4";
parameter2 = parameter2 + " ";
strcat(command,parameter2.c_str());
//parameter3
string parameter3 = argv[3];
parameter3 = parameter3 + " ";
strcat(command,parameter3.c_str());
//parameter4
strcat(command,argv[4]);
cout<<"command:"<<command<<endl;
system(command);
}
}
return 0;
}
flower.sh脚本文件
#!/bin/sh
echo "$1" #input file name
echo "$2" #output file name
echo "$3" #start time
echo "$4" #end time
ffmpeg -i /home/cidi/Documents/test_video/$1 -vcodec copy -acodec copy -ss $3 -to $4 /home/cidi/Documents/test_video/$2 -y
这样我就可以解决我的问题啦!具体细节有问题的同学可以下方留言板戳我!