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

#!/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

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐