shell FFMPEG静音分割(具有实现12个分割段的逻辑)

57hvy0tb  于 2023-03-19  发布在  Shell
关注(0)|答案(2)|浏览(194)

https://github.com/MartinBarker/split_by_silence
我正试图自动分割成12个轨道的单个音频文件的过程。你可以在下面的图像中看到,这个35:62长度的MP3文件有11个可见的分割点(音频更安静的地方),这意味着12个不同的片段。

我希望能够运行脚本来自动查找这些拆分点并拆分我的文件,我的第一个拆分点应该在159秒左右,第二个拆分点在360左右,第三个拆分点在540左右,第四个拆分点在780左右,第五个拆分点在960左右,以此类推,总共11个拆分点:
但我的测试结果不太好

- Goal:
11 split points found
12 tracks rendered

- Test 1
SD_PARAMS="-24dB"
MIN_FRAGMENT_DURATION="3"
5 split points found: 361.212,785.811,790.943,969.402,2150.24`
6 tracks rendered

-Test 2
SD_PARAMS="-24dB"
MIN_FRAGMENT_DURATION="3"
10 split points found: 151.422,155.026,158.526,361.212,534.254,783.667,967.253,1128.91,2150.2
11 tracks rendered
  • 测试2问题:即使渲染了12个轨迹,一些分割点也非常接近

    ,导致导出的轨迹非常短,如3、5和2秒,以及一个长轨迹为16分钟

因此,我添加了一个变量MIN_SEGMENT_LENGTH并运行了另一个测试

- Test 3
SD_PARAMS="-18dB"
MIN_FRAGMENT_DURATION="3"
MIN_SEGMENT_LENGTH=120 (02:00)

log:
_______________________
Determining split points...
split points list= 150.482,155.026,158.526,361.212,530.019,534.254,783.667,967.245,1127.67,2144.57,2150.2
1. The difference between 150.482 and 155.026 is 4.544
       diff is less than MIN_SEGMENT_LENGTH=120
2. The difference between 155.026 and 158.526 is 3.500
       diff is less than MIN_SEGMENT_LENGTH=120
3. The difference between 158.526 and 361.212 is 202.686
4. The difference between 361.212 and 530.019 is 168.807
5. The difference between 530.019 and 534.254 is 4.235
       diff is less than MIN_SEGMENT_LENGTH=120
6. The difference between 534.254 and 783.667 is 249.413
7. The difference between 783.667 and 967.245 is 183.578
8. The difference between 967.245 and 1127.67 is 160.425
9. The difference between 1127.67 and 2144.57 is 1016.90
10. The difference between 2144.57 and 2150.2 is 5.63
       diff is less than MIN_SEGMENT_LENGTH=120
_______________________
Exporting 12 tracks with ffmpeg...

我不知道如何改变我的脚本和变量,以便通过运行它,计算分割点,如果他们中的任何一个太短(不到120秒)重新生成分割点?
下面是我的音频文件:https://filetransfer.io/data-package/HC7GG07k#link
这是我的脚本,可以通过运行./split_by_silence.sh来运行它

# -----------------------
# SPLIT BY SILENCE
# Requirements:
#    ffmpeg
#    $ apt-get install bc
# How To Run:
# $ ./split_by_silence.sh "full_lowq.flac" %03d_output.flac

# output title format
OUTPUTTITLE="%03d_output.mp3"
# input audio filepath
IN="/mnt/e/martinradio/rips/vinyl/L.T.D. – Gittin' Down/lowquality_example.mp3"
# output audio filepath
OUTPUTFILEPATH="/mnt/e/folder/rips"
# ffmpeg option: split input audio based on this silencedetect value
SD_PARAMS="-18dB"
# split option: minimum fragment duration
MIN_FRAGMENT_DURATION=3
# minimum segment length
MIN_SEGMENT_LENGTH=120

# -----------------------
# step: ffmpeg
# goal: get comma separated list of split points (use ffmpeg to determine points where audio is at SD_PARAMS [-18db] )

echo "_______________________"
echo "Determining split points..." >& 2
SPLITS=$(
    ffmpeg -v warning -i "$IN" -af silencedetect="$SD_PARAMS",ametadata=mode=print:file=-:key=lavfi.silence_start -vn -sn  -f s16le  -y /dev/null \
    | grep lavfi.silence_start= \
    | cut -f 2-2 -d= \
    | perl -ne '
        our $prev;
        INIT { $prev = 0.0; }
        chomp;
        if (($_ - $prev) >= $ENV{MIN_FRAGMENT_DURATION}) {
            print "$_,";
            $prev = $_;
        }
    ' \
    | sed 's!,$!!'
)
echo "split points list= $SPLITS"
# determine if the difference between any two splits is less than MIN_SEGMENT_LENGTH seconds
IFS=',' read -ra VALUES <<< "$SPLITS"

for (( i=0; i<${#VALUES[@]}-1; i++ )); do
  diff=$(echo "${VALUES[$i+1]} - ${VALUES[$i]}" | bc)
  display_i=$((i+1))
  echo "$display_i. The difference between ${VALUES[$i]} and ${VALUES[$i+1]} is $diff"
  if (( $(echo "$diff < $MIN_SEGMENT_LENGTH" | bc -l) )); then
    echo "       diff is less than MIN_SEGMENT_LENGTH=$MIN_SEGMENT_LENGTH"
  fi
done

# using the split points list, calculate how many output audio files will be created 
num=0
res="${SPLITS//[^,]}"
CHARCOUNT="${#res}"
num=$((CHARCOUNT + 2))
echo "_______________________"
echo "Exporting $num tracks with ffmpeg"

ffmpeg -i "$IN" -c copy -map 0 -f segment -segment_times "$SPLITS" "$OUTPUTFILEPATH/$OUTPUTTITLE"

echo "Done."
5anewei6

5anewei61#

要从源视频中选择剪辑,请执行以下命令:

#To clip video from 0-159 sec:

ffmpeg -i movie.mp4 -ss 00:00:00 -t 00:02:39 -async 1 cut.mp4

#To clip video from 160-360 sec:
ffmpeg -i movie.mp4 -ss 00:02:40 -t 00:03:20 -async 1 cut2.mp4 

# -ss means start timestamp
# -t means duration

我没有找到唯一的持续时间模式,我将重新编写shell脚本。

798qvoo8

798qvoo82#

适用于MP3,但我得到一个新的错误flac文件:ffmpeg split_by_silence output flac have broken metadata
这是我的mp3修复,我通过添加export MIN_FRAGMENT_DURATION和调整值来修复它

SD_PARAMS="-11dB"
MIN_FRAGMENT_DURATION=120

以下是完整的脚本

# -----------------------
# SPLIT BY SILENCE
# Requirements:
#    ffmpeg
#    $ apt-get install bc
# How To Run:
# $ ./split_by_silence.sh "full_lowq.flac" %03d_output.flac

# output title format
OUTPUTTITLE="%d_output.mp3"
# input audio filepath
IN="/mnt/c/Users/marti/Documents/projects/split_by_silence/lowquality_example.mp3"
# output audio filepath
OUTPUTFILEPATH="/mnt/c/Users/marti/Documents/projects/split_by_silence"
# ffmpeg option: split input audio based on this silencedetect value
SD_PARAMS="-11dB"
# split option: minimum fragment duration
MIN_FRAGMENT_DURATION=120
export MIN_FRAGMENT_DURATION

#  close (12 tracks)
#  -11db
#  120

# -----------------------
# step: ffmpeg
# goal: get comma separated list of split points (use ffmpeg to determine points where audio is at SD_PARAMS [-18db] )

echo "_______________________"
echo "Determining split points..."
SPLITS=$(
    ffmpeg -v warning -i "$IN" -af silencedetect="$SD_PARAMS",ametadata=mode=print:file=-:key=lavfi.silence_start -vn -sn  -f s16le  -y /dev/null \
    | grep lavfi.silence_start= \
    | cut -f 2-2 -d= \
    | perl -ne '
        our $prev;
        INIT { $prev = 0.0; }
        chomp;
        if (($_ - $prev) >= $ENV{MIN_FRAGMENT_DURATION}) {
            print "$_,";
            $prev = $_;
        }
    ' \
    | sed 's!,$!!'
)
echo "split points list= $SPLITS"

# using the split points list, calculate how many output audio files will be created 
num=0
res="${SPLITS//[^,]}"
CHARCOUNT="${#res}"
num=$((CHARCOUNT + 2))
echo "_______________________"
echo "Exporting $num tracks with ffmpeg"

ffmpeg -i "$IN" -c copy -map 0 -f segment -segment_times "$SPLITS" "$OUTPUTFILEPATH/$OUTPUTTITLE"

echo "Done."

echo "------------------------------------------------"
echo "$num TRACKS EXPORTED"

相关问题