问题情景
体验某云语音听写(或语音转写、语音识别)API时的,音频文件中出现超过2-3s左右的间隔就停止识别了,漏听了一大段内容。又不想自己手动边听边裁剪,怎么办呢。
ffprobe 23ll.wav语音文件信息:Duration时长有44s
44s怎么可能才说这么点字ffmpeg查看响度信息
ffmpeg -i 23ll.wav -af volumedetect -f null dummy好了,用ffmpeg volumedetect滤镜看到了响度(db)的统计信息,最大值,最小值,怎么看到每一时间的响度呢
ffmpeg -i 23ll.wav -filter_complex "showwavespic=s=1024x768:split_channels=1" -frames:v 1 23ll.png 试试showwavespic,这个图没坐标轴,不好看,而且量纲也不知道,再试试scilab,octave/matlab
scilab,octave/matlab 画响度时间图 再根据它用silenceremove
1.octave/matlab代码(maxdb值来自ffmpeg -af volumedetect)
代码语言:javascript复制close all;clf
try;pkg load signal;catch;end;
db=@(x)log10(abs(x))*20; %根据分贝的定义
[y,fs]=audioread('23ll.wav','native');
maxdb=-1.5;
%//get from ffmpeg -i 23ll.wav -af volumedetect -f null dummy
y=db(y);y=y maxdb-max(y);
plot([1:length(y)]/fs,y);xlabel('t (s)');ylabel('y (db)');
saveas(gcf,'23ll.jpg','jpg');
%sound(y,fs);
时间响度图1(过滤前的原23ll.wav)中间有几个响度低于-40db的沟壑显然没语音
放大来看,16.5~19.5有一段低于-40db的沟壑,估为2.5s吧于是ffmpeg -i 23ll.wav -af silenceremove=stop_periods=-1:stop_duration=2.5:stop_threshold=-40dB 23lloutput1.wav
duration时长从44s变成了39s左右,喂给API试一下
识别结果长了一点,但是不够39s的,再看看有什么问题scilab代码(maxdb值来自ffmpeg -af volumedetect)(功能一样写法不同)
代码语言:javascript复制function y=db(x);
y=log10(abs(x))*20;
endfunction;
[y, fs, bits] = wavread('23lloutput1.wav');
maxdb=-1.5;
//get from ffmpeg -i 23ll.wav -af volumedetect -f null dummy
y=db(y);y=y maxdb-max(y);
plot([1:length(y)]/fs,y);xlabel('t (s)');ylabel('y (db)');
scilab图 显然还有31s有个小于-40db的沟壑
滚轮放大后拖动画面,有30.5-32.5s长达2s的低于-40db的沟壑于是再来一遍,stop_duration改成2,ffmpeg -i 23ll.wav -af silenceremove=stop_periods=-1:stop_duration=2:stop_threshold=-40dB 23lloutput2.wav
duration时长又减到了38.25s,喂给API试一下
这次结果很好再用scilab看看响度/时间关系图
scilab中的代码
完美,太长的间隔都被清除了, 收工

