' C'程序将音频文件输出到FFMPEG并生成视频文件

时间:2017-05-08 17:18:05

标签: c audio video ffmpeg

我正在尝试写一篇短片' C'使用FFMPEG读取音频文件的程序,使用' C'程序,然后通过FFMEPG输出文件,FFMEPG使用FFMPEG showwaves过滤器将新的,修改过的音频与视频表示相结合。

目前该计划尝试执行以下操作: -

i)使用pipein thorugh FFMPEG读入音频文件 ii)使用“C'”的一部分处理音频文件。程序 iii)将修改后的音频输出到FFMPEG,并使用“showwaves”生成文件。在FFMEPG中过滤以创建带有音频和视频的MP4文件。

以下代码从FFMPEG中的ommand行运行生成我想要创建的音频/视频MP4: -

ffmpeg -y -f s16le -ar 44100 -ac 1 -i 12345678.wav  -i 12345678.wav  -filter_complex  "[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" -map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  12345678.mp4

"

此代码生成已处理的音频文件,并根据需要将其输出到.wav文件: -

#include <stdio.h>
#include <stdint.h>
#include <math.h>

void main()
{
// Launch two instances of FFmpeg, one to read the original WAV
// file and another to write the modified WAV file. In each case,
// data passes between this program and FFmpeg through a pipe.
FILE *pipein;
FILE *pipeout;
pipein  = popen("ffmpeg -i 12345678.wav -f s16le -ac 1 -", "r");
pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i - out.wav", "w");

// Read, modify and write one sample at a time
int16_t sample;
int count, n=0;
while(1)
{
    count = fread(&sample, 2, 1, pipein); // read one 2-byte sample
    if (count != 1) break;
    ++n;
    sample = sample * sin(n * 5.0 * 2*M_PI / 44100.0);
    fwrite(&sample, 2, 1, pipeout);
}

// Close input and output pipes
pclose(pipein);    
pclose(pipeout);
}

(此代码借鉴了特德伯克的优秀帖子here

我已尝试如下所示,但这不起作用: -

#include <stdio.h>
#include <stdint.h>
#include <math.h>

void main()
{
// Launch two instances of FFmpeg, one to read the original WAV
// file and another to write the modified WAV file. In each case,
// data passes between this program and FFmpeg through a pipe.
FILE *pipein;
FILE *pipeout;
pipein  = popen("ffmpeg -i 12345678.wav -f s16le -ac 1 -", "r");
pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i 12345678.wav  -i 
12345678.wav  -filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4
", "w");


// Read, modify and write one sample at a time
int16_t sample;
int count, n=0;
while(1)
{
    count = fread(&sample, 2, 1, pipein); // read one 2-byte sample
    if (count != 1) break;
    ++n;
    sample = sample * sin(n * 5.0 * 2*M_PI / 44100.0);
    fwrite(&sample, 2, 1, pipeout);
}

// Close input and output pipes
pclose(pipein);    
pclose(pipeout);
}    

理想情况下,有人可以建议上面的管道输出命令的改进版本 - 另外另一个实现此目的的过程将是有趣的

*编辑*

感谢@Mulvya,修改后的管道输出线现在是: -

pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -filter_complex  "[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" -map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  12345678.mp4

&#34;,&#34; w&#34;);

在使用gcc编译时,我收到以下错误消息: -

avtovid2.c: In function \u2018main\u2019:

wavtovid2.c:13:83: error: expected \u2018]\u2019 before \u2018:\u2019 
token
 pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -
filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4

^
wavtovid2.c:13:86: error: expected \u2018)\u2019 before 
\u2018showwaves\u2019
 pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -
filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4

^
wavtovid2.c:13:98: error: invalid suffix "x720" on integer constant
 pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -
filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4

^
wavtovid2.c:13:153: warning: missing terminating " character
 pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -
filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4

^
wavtovid2.c:13:86: error: missing terminating " character
 pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -
filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4

^
wavtovid2.c:14:6: warning: missing terminating " character
 ", "w");
  ^
wavtovid2.c:14:1: error: missing terminating " character
 ", "w");
 ^
wavtovid2.c:13:21: warning: passing argument 1 of \u2018popen\u2019 makes 
pointer from integer without a cast
 pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -
filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4
                 ^
In file included from wavtovid2.c:1:0:
/usr/include/stdio.h:872:14: note: expected \u2018const char *\u2019 but 
argument is of type \u2018char\u2019
 extern FILE *popen (const char *__command, const char *__modes) __wur;
          ^
wavtovid2.c:13:15: error: too few arguments to function \u2018popen\u2019
 pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -
filter_complex  "
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v]" -map "[v]" 
-map 1:a:0 -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -
codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart  
12345678.mp4
           ^ 
In file included from wavtovid2.c:1:0:
/usr/include/stdio.h:872:14: note: declared here
 extern FILE *popen (const char *__command, const char *__modes) __wur;
          ^
wavtovid2.c:32:1: error: expected \u2018;\u2019 before \u2018}\u2019 
token
 }

1 个答案:

答案 0 :(得分:0)

这是一个工作版本 - 感谢@Mulvya的帮助,感谢Ted Burke的原始代码。

该程序将通过FFMPEG读入名为12345678.wav的文件,并在&#39; C&#39;中处理该文件。产生颤音效果,然后将音频输出到名为12345678.mp4的视频文件中,并使用FFMEPG&lt; showwaves&#39;生成视频。过滤器: -

#include <stdio.h>
#include <stdint.h>
#include <math.h>

void main()
{
// Launch two instances of FFmpeg, one to read the original WAV
// file and another to write the modified WAV file. In each case,
// data passes between this program and FFmpeg through a pipe.
FILE *pipein;
FILE *pipeout;
pipein  = popen("ffmpeg -i 12345678.wav -f s16le -ac 1 -", "r");
pipeout = popen("ffmpeg -y -f s16le -ar 44100 -ac 1 -i -  -filter_complex  
[0:a]showwaves=s=1280x720:mode=line:rate=25,format=yuv420p[v] -map [v] -
map 0:a  -codec:a aac -strict -2  12345678.mp4", "w");


// Read, modify and write one sample at a time
int16_t sample;
int count, n=0;
while(1)
{
    count = fread(&sample, 2, 1, pipein); // read one 2-byte sample
    if (count != 1) break;
    ++n;
    sample = sample * sin(n * 5.0 * 2*M_PI / 44100.0);
    fwrite(&sample, 2, 1, pipeout);
    }

    // Close input and output pipes
    pclose(pipein);    
    pclose(pipeout);
}

这仍然需要一些工作来理解FFMPEG管道限制,并改进输出文件规范。

该程序的目的是作为开发程序的第一步,该程序可以接受和处理C&#39;中的音频文件,并使用FFMPEG生成组合的音频和视频输出。