如何编写支持标准输入输出、适配Bash管道调用的C程序
解决方案
要实现你的需求,核心要解决两个问题:从命令行获取输入源、将ffmpeg处理结果输出到标准输出,以下是具体实现步骤和代码示例:
1. 读取命令行输入参数
C程序通过argc(参数数量)和argv(参数数组)获取命令行传入的内容。比如执行c_programme input.mp4时,argv[1]就是输入文件的路径;如果用户使用重定向c_programme < input.mp4,则可以让ffmpeg从标准输入读取数据(用-i -)。
2. 构造ffmpeg命令并导向标准输出
- 输入命令:将硬编码的文件名替换为用户传入的参数,或用
-读取标准输入。 - 输出命令:将原代码中的输出文件名
output.mp4替换为-,表示ffmpeg将结果输出到标准输出;同时添加-loglevel quiet避免ffmpeg的日志信息干扰管道数据。
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFER_SIZE 4096 #define CMD_SIZE 1024 int main(int argc, char *argv[]) { char input_cmd[CMD_SIZE]; char output_cmd[CMD_SIZE]; FILE *pipein, *pipeout; char buffer[BUFFER_SIZE]; size_t bytes_read; // 构造输入命令:优先使用命令行参数,无参数则从标准输入读取 if (argc >= 2) { snprintf(input_cmd, CMD_SIZE, "ffmpeg -i %s -f image2pipe -vcodec rawvideo -pix_fmt rgb24 -", argv[1]); } else { snprintf(input_cmd, CMD_SIZE, "ffmpeg -i - -f image2pipe -vcodec rawvideo -pix_fmt rgb24 -"); } // 构造输出命令:输出到标准输出,关闭日志避免干扰 snprintf(output_cmd, CMD_SIZE, "ffmpeg -y -f rawvideo -vcodec rawvideo -pix_fmt rgb24 -s 1280x720 -r 25 -i - -f mp4 -q:v 50 -an -vcodec mpeg4 -loglevel quiet -"); // 打开输入管道 pipein = popen(input_cmd, "r"); if (!pipein) { perror("Failed to open input pipe"); return EXIT_FAILURE; } // 打开输出管道 pipeout = popen(output_cmd, "w"); if (!pipeout) { perror("Failed to open output pipe"); pclose(pipein); return EXIT_FAILURE; } // 传递管道数据:从输入管道读,写入输出管道 while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, pipein)) > 0) { fwrite(buffer, 1, bytes_read, pipeout); } // 关闭管道并检查状态 if (pclose(pipein) == -1) { perror("Failed to close input pipe"); return EXIT_FAILURE; } if (pclose(pipeout) == -1) { perror("Failed to close output pipe"); return EXIT_FAILURE; } return EXIT_SUCCESS; }
编译与使用
- 编译代码:
gcc -o c_programme c_programme.c - 复制到系统可执行目录:
sudo cp c_programme /usr/bin/ - 调用方式:
- 传入文件名参数:
c_programme input.mp4 | another_program - 使用重定向输入:
c_programme < input.mp4 | another_program
- 传入文件名参数:
内容的提问来源于stack exchange,提问作者1toneboy
相关产品推荐
相关产品推荐

