ffmpeg按静音批量切分音频文件脚本

该脚本主要利用FFmpeg工具对MP3文件进行静音检测,通过设定的噪声容忍值和静音时长参数,找出静音段并进行分割。它首先生成一个日志文件记录静音起点和终点,然后解析这个日志来分割音频文件,将非静音部分保存到指定目录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小朋友觉得单个英语音频文件太长了,重听一句话,要手动拉来拉去,太费体力;做个小工具自用,按静音把音频文件切分为多个文件,对于规规矩矩朗读的音频可以比较准确的切分,基本够用了。

#!/bin/bash
#王道元

g_NOISE=-40dB #噪声容忍值,单位为dB,默认为-60dB
g_DURATION=0.40 #duration, d:设置静音时长,默认为2s; 根据不同情况设置有0.4,1.0等
g_START_AD=0.25 #上次静音结束位置往前调整值 秒
g_TIME_AD=0.5 #截取时长调整值 秒

split_audio(){
    #split_audio mp3file 上个静音结束时间 当前静音开始时间 序号 分割文件存储目录
    lfile=$1
    llast_end=$2
    lcur_start=$3
    lind=$4
    ldstdir=$5
    lbase=`echo  ${lfile%%.*}`  #取文件名 Book1-001.mp3之Book1-001
    ltype=`echo ${lfile#*.}`  #取后缀 mp3
    ldst=$ldstdir"/"$lbase"_"$lind"."$ltype  #/abcw/Book1-001_1000.mp3
#    echo " "$1" "$2" "$3" "$ldst

    # ss = END_1 - Delta, t = START_2 - END_1 + Delta +Delta
    lss=$(printf "%.5f" `echo "scale=5; $llast_end - $g_START_AD" | bc`)
    lt=$(printf "%.5f" `echo "scale=5; $lcur_start - $llast_end +  $g_TIME_AD" | bc`)
    echo "ffmpeg -i $lfile -ss $lss -t $lt $ldst -hide_banner -y"
    ffmpeg -i $lfile -ss $lss -t $lt $ldst -hide_banner -y  -f null - 2> /dev/null
}

gen_silence_log(){
    lfile=$1
    llog=$2
    echo "ffmpeg -i $lfile -af silencedetect=noise=$g_NOISE:d=$g_DURATION -hide_banner -f null - 2> $llog"
    ffmpeg -i $lfile -af silencedetect=noise=$g_NOISE:d=$g_DURATION -hide_banner -f null - 2> $llog
#    cp $llog $PWD/"origlog"
    sed -i '/^\s*$/d'  $llog
    sed -i '/^[^\[].*$/d'  $llog #删除非[开头行
    sed -i '/^\[[^s].*$/d'  $llog #删除非[s开头行
    sed -i 's/\[s.*\]//g'  $llog #删除[silencedetect *]
    sed -i 's/|.*//g'  $llog #删除 | 及之后内容
    sed -i 's/[[:space:]]//g'  $llog #删除所有空格
    sed -i 's/silence_//g'  $llog 
#    cp $llog $PWD/"fmtlog"
}


parse_log(){
    lfile=$1
    llog=$2
    ldstdir=$3

    let lind=1000  #分割后文件起始序号,1开头确保相同宽度
    let llast_end=-1 #上一个end为-1, 则为本文件第一个静音段,此段start忽略

#    while read  -r lline;    do #使用while read 会导致读取行错误
    for lline in `cat $llog`; do
        echo "TimsStamp Line:"$lline
        lname=`echo  ${lline%%:*}`  #silence_start: 82.62  取silence_start或end
        lvalue=`echo ${lline#*:}`   #silence_start: 82.62  取82.62

        echo "NAME:"$lname" VALUE: "$lvalue

        if [ "start" ==  $lname ]  ;  then
            if [ -1 != $llast_end ] ; then
                lcur_start=$lvalue
                echo "split_audio $lfile $llast_end $lcur_start $lind $ldstdir"
                split_audio $lfile $llast_end $lcur_start $lind $ldstdir 
                #split_audio mp3 上个静音结束时间 当前静音开始时间 序号 分割文件存储目录
                let lind++
                sleep 1
            fi
              else
            llast_end=$lvalue
             fi
     done
#    done < $llog
}

for file in `ls *.mp3`
do
    echo $file
    lbase=`echo  ${file%%.*}`  #取文件名前缀 Book1-001
    ldstdir=$lbase"d" #文件截分后保存目录
    ldstlog=$ldstdir"/vol"

    echo  "lbase:" $lbase "  ldstdir: " $ldstdir " ldstlog: " $ldstlog

    rm -rf $ldstdir
    mkdir $ldstdir

    gen_silence_log $file $ldstlog
    parse_log $file $ldstlog $ldstdir
    rm -f  $ldstlog
done

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值