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

这样我就可以解决我的问题啦!具体细节有问题的同学可以下方留言板戳我!

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