c++程序調用shell腳本,並向shell傳入參數,shell腳本利用ffmpeg批量切割視頻文件

  • 任務:在linux平臺下多次調用ffmpeg來切割多個視頻
  • 思考與難點:既然需要多次調用命令行命令ffmpeg,自然而然想到需要寫一個shell腳本在c++程序中調用這個腳本就行了,但是問題並沒有這麼簡單。c++程序中如何調用shell腳本?該怎麼向shell腳本傳入參數呢?shell腳本又是怎樣來接受參數的

1、c++程序中如何調用shell腳本?

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

這樣我就可以解決我的問題啦!具體細節有問題的同學可以下方留言板戳我!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章