音声あり部分の開始・終了の秒数を取得するにはどうすれば良い?
こんな疑問にお答えします。
Pythonで音声ファイルを扱う際に、無音の部分でファイルを分割するためにsplit_on_silence
はよく使われます。
その際に、分割された音声ファイルの開始と終了の秒数を使ってなんやかんやしたいこともあるかと思います。
私はOpenAIのWhisperに渡す時に綺麗に分割するために必要でした。
その際、ちょっとクセがあり若干ハマってしまったのでその備忘録も兼ねて、今回はpydubのsplit_on_silenceで音声あり部分の開始・終了の秒数を取得する方法を解説したいと思います。
split_on_silenceで音声あり部分の開始・終了の秒数を取得する方法
pydubのsplit_on_silence
を使って音声あり部分の開始・終了の秒数を取得することはできません。
いきなりなんじゃそりゃ〜という感じかもですが…
というのも、split_on_silence
にはそういった情報を返却するようになっていないためです。
では、どうすれば音声あり部分の開始・終了の秒数を取得をできるのでしょうか。
それは、detect_nonsilent
を使うことでできます。
【真】音声あり部分の開始・終了の秒数を取得する方法
上記でも述べましたが、音声あり部分の開始・終了の秒数を取得するにはpydubのsplit_on_silence
ではなく、detect_nonsilent
を使うことでできます。
split_on_silenceと同じpydub.silenceモジュールからインポートできます。
具体的には、以下のようにして音声ありの部分の開始と終了の秒数(ms)を取得できます。
from pydub.silence import detect_nonsilent
def get_timestamp_for_nonslience(
file: str, silence_threshold=-50, min_silence_duration=500
) -> list[list[int]]:
#1
audio = AudioSegment.from_file(file)
#2
segments = detect_nonsilent(
audio, min_silence_len=min_silence_duration, silence_thresh=silence_threshold
)
#3
return segments
以下で簡単に説明します。
#1の部分:AudioSegmentの生成
上記の#1の部分であるaudio = AudioSegment.from_file(file)
では、ファイルをAudioSegmentに変換しています。
これは次のdetect_nonsilent
で必要になります。
#2の部分:音声ファイルの分割
detect_nonsilent
を使って、min_silence_len
とsilence_thresh
をもとに音声がある部分で音声ファイルを分割します。
detect_nonsilent
の返却値として、分割された各音声ファイルの開始と終了の秒数(ms)がリスト形式として返却されます。
[[1234, 2345], [4321, 7890]…]みたいな感じです。
#3の部分:開始と終了の秒数データを返却
関数の返却値として、分割して得た音声ありの開始と終了の秒数を返却します。
以上の手順で、簡単に音声ファイルの音声あり部分の開始・終了の秒数を取得することができます。
今後split_on_silenceでも開始・終了の秒数が取得できるようになる?
ここまででお伝えしたように、音声あり部分の開始・終了の秒数を取得するにはsplit_on_silence
ではなくdetect_nonsilent
を使うことでできるのでした。
ただ、今後は以下のPRがマージされればsplit_on_silence
でも同じことができるようになるかもしれません。
https://github.com/jiaaro/pydub/pull/442
PRの内容としては、split_on_silence
の引数としてwith_timing
を渡してそれがTrueの場合に開始と終了の秒数を返却するようになっています。
ただしPR自体が2020年とかなり古く、いまだにマージされていないことを考えると今後もdetect_nonsilent
使うしかないかもしれないですが…
音声あり部分の開始・終了の秒数はdetect_nonsilentで取得可能:まとめ
今回は、音声ファイルの音声あり部分の開始・終了の秒数を取得する方法としてpydubのdetect_nonsilent
を使う方法を紹介しました。
無音で音声を分割するsplit_on_silence
はよく使うと思いますが、音声の開始と終わりの秒数がわからないのは少し不便ですよね。
音声あり部分の開始・終了の秒数が必要な場合には、ぜひdetect_nonsilent
を活用ください。