如何在php中用ffmpeg修剪音频的沉默

时间:2015-09-09 01:35:24

标签: php ffmpeg

我的托管没有ffmpeg的silenceremove过滤器,因此我尝试删除音频文件的开头和结尾静音silencedetect然后剪切。我试图用PHP以编程方式执行此操作。在这一点上,我甚至无法发现沉默。我试过了:

define('UPLOAD_DIR', $_SERVER['DOCUMENT_ROOT'].'/audiofiles/');
$filein = UPLOAD_DIR . "music.ogg";
$fileout = UPLOAD_DIR . "music_no_silence.ogg";
$fileouttxt = UPLOAD_DIR . "music_log.txt";
$ffmpeg = "/usr/local/ffmpeg/bin/ffmpeg";

我首先尝试将ffmpeg命令放入变量,然后尝试访问输出但无法执行:

$output = shell_exec("$ffmpeg -i $filein -af silencedetect=n=-50dB:d=1");
echo $output;

然后我尝试创建转换的.txt日志,但.txt文件并未显示有关silencedetect的任何信息。此外,我如何才能从.txt日志中以编程方式提取我需要的信息才能在php中使用它?

shell_exec("$ffmpeg -i $filein -af silencedetect=n=-50dB:d=1 $fileout 2> $fileouttxt");

我基本上试图将https://stackoverflow.com/a/25698675的答案调整为php

修改:这是一种破解方式:

define('UPLOAD_DIR', $_SERVER['DOCUMENT_ROOT'].'/audiofiles/');
$filein = UPLOAD_DIR . "music.ogg";
$fileout1 = UPLOAD_DIR . "music_out1.ogg";
$fileout2 = UPLOAD_DIR . "music_out2.ogg";
$ffmpeg = "/usr/local/ffmpeg/bin/ffmpeg";
$command = "$ffmpeg -i $filein -filter_complex silencedetect=n=-10dB:d=0.5 -y $fileout1 2>&1";

$output = array();
exec($command,$output);

$searchword1 = 'silence_end';
$endmatches = array_filter($output, function($var) use ($searchword1) {return preg_match("/\b$searchword1\b/i", $var);});
$endmatches = array_values($endmatches);

$parts1 = explode(" ",$endmatches[0]);
$a = $parts1[4];
$a = $a-.5;

$searchword2 = 'silence_start';
$startmatches = array_filter($output, function($var) use ($searchword2) {return preg_match("/\b$searchword2\b/i", $var);});
$startmatches = array_values($startmatches);

$parts2 = explode(" ",end($startmatches));
$b = $parts2[4];
$b = $b+.5;

$c = $b-$a;

exec("$ffmpeg -i $fileout1 -ss $a -t $c -y $fileout2 && rm $fileout1");

1 个答案:

答案 0 :(得分:2)

PHP shell_exec返回写入stdout的输出,ffmpeg将消息写入stderr。如果您要使用shell_exec,则必须使用stderrstdout输出重定向到2>&1

您还需要为ffmpeg指定至少一个输出文件,在本例中为/dev/null

set_time_limit(0);

$input_file = 'music.ogg';
$cmd = "ffmpeg -i {$input_file} -af silencedetect=n=-50dB:d=1 -f null /dev/null 2>&1";
$output = shell_exec($cmd);

if (preg_match_all("/^\[silencedetect\s[^]]+\]\s([^\n]+)/m", $output, $matches)) {
    var_export($matches[1]);
}

另一种方法是使用proc_openstream_get_contents