2017-05-08 116 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生成組合的音頻和視頻輸出。

相關問題