- 任務:在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
這樣我就可以解決我的問題啦!具體細節有問題的同學可以下方留言板戳我!