2017-05-08 114 views
0

我正在尝试编写一个简短的'C'程序,它使用FFMPEG读取音频文件,使用'C'程序处理该文件,然后输出一个通过FFMEPG的文件,它使用FFMPEG showwaves过滤器将新的修改过的音频与视频表示结合在一起。'C'程序将音频文件转换为FFMPEG并生成视频文件

目前程序试图执行以下操作: -

ⅰ)读出在音频文件,使用pipein thorugh FFMPEG ⅱ)过程中使用的“C”的一部分的音频文件程序 ⅲ)将修改过的音频输出到FFMPEG,并使用FFMEPG中的'showwaves'过滤器生成一个文件,以创建一个包含音频和视频的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); 
}  

理想的人可以建议pipeout命令的改进版本以上 - 交替另一个进程来实现,这将是有趣

*编辑*

由于@Mulvya,修订后的pipeout行现在是: -

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 

“,”w“);

在用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 
} 
+0

您正在读取管道,但您的第二个命令是从文件读取,而不是管道。您在pipeout中的输入应该是'-f s16le -ar 44100 -ac 1 -i -'。您也可以重复使用两次映射音频'-map 0:a'。无需输入第二个输入。最后,ffmpeg不会编辑文件,因此输入和输出文件不能相同。 – Mulvya

+0

感谢您输入@Mulvya - 当然输入文件的阅读是错误的。关于映射音频 - 要使命令在终端的FFMEPG内正确运行,我发现我需要声明音频和视频输入文件,否则'showwaves'不会从音频源生成视频。尽管如此,c编译器还是发现了一些ffpmeg命令的语法错误。 – soflow

+0

删除filter_complex字符串周围的双引号,并将'-map 1:a:0'更改为'-map 0:a'。 – Mulvya

回答

0

这里是一个工作版本 - 感谢@Mulvya的帮助和特德·伯克提供原代码。

该程序将通过FFMPEG在名为12345678.wav的文件中读取,处理该文件的'C'以产生颤音效果,然后将该音频输出到名为12345678.mp4的视频文件中,并使用FFMEPG“showwaves”过滤器: -

#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'中的音频文件,并使用FFMPEG生成组合的音频和视频输出。

相关问题