簡體   English   中英

“ C”程序將音頻文件輸出到FFMPEG並生成視頻文件

[英]'C' program to pipeout audio file to FFMPEG and generate Video file

我正在嘗試編寫一個簡短的“ C”程序,該程序使用FFMPEG讀取音頻文件,使用“ C”程序處理該文件,然后通過FFMEPG輸出文件,該文件將新的修改后的音頻與視頻表示形式結合在一起使用FFMPEG showwaves過濾器。

目前,該程序嘗試執行以下操作:

i)使用流水線FFMPEG讀取音頻文件ii)使用“ C”程序的一部分處理音頻文件iii)將修改后的音頻流式傳輸到FFMPEG,並使用FFMEPG中的“ showwaves”過濾器生成文件以創建帶有音頻和視頻的MP4文件。

從FFMPEG中的指令行運行以下代碼會生成我要創建的音頻/視頻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);
}

(此代碼從特德·伯克出色的后借這里

我已經嘗試過如下所示的操作,但這不起作用:

#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 = 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
 }

這是一個工作版本-感謝@Mulvya的幫助,以及Ted Burke的原始代碼。

該程序將通過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生成組合的音頻和視頻輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM