Skip to content

Instantly share code, notes, and snippets.

@watiko
Last active February 24, 2021 04:59
Show Gist options
  • Save watiko/6c69fcd4b6b3d70cdf5af0d84ae31ef0 to your computer and use it in GitHub Desktop.
Save watiko/6c69fcd4b6b3d70cdf5af0d84ae31ef0 to your computer and use it in GitHub Desktop.
bms2preview

事前準備

依存するコマンド

  • bms-renderer: BMSをwavに変換する
    • npm install --global @watiko/bms-renderer
      • 本家で対応されたら本家を入れると良い
    • libsndfileが必要なので用意しておく。debianでは apt install libsndfile1-dev
  • sox: 先頭の無音部分を削除
  • ffmpeg: oggに変換しつつ、頭出しから10秒を切り出す

使う

find . -name '*.bme' -o -name '*.bms' -o -name '*.bml' -print0 \
  | xargs -0 -I{} dirname '{}' \
  | xargs -P 0 -I{} /path/to/bms2preview.bash '{}'

検証

テスト用のBMSを用意

お好みのものを test-bms.zip として保存しましょう。

$ mkdir tmp && cd $_
$ ls test-bms.zip
$ unzip -d extracted -j ../test-bms.zip

BMSからwavを生成し、ファイルの音がある部分からプレビューを生成する

$ cd tmp/extracted
$ ls *.bme | head -n1 | xargs -I{} bms-renderer "{}" tmp1.wav
$ sox tmp1.wav tmp2.wav vad
$ ffmpeg \
  -i tmp2.wav \
  -t 10 \
  -vn -ab 160k -acodec libvorbis -f ogg \
  -loglevel warning \
  preview_music.ogg
$ rm tmp1.wav tmp2.wav
set -eo pipefail
function bms2wav() {
local _bms="$1"
local _wav="$2"
bms-renderer "$_bms" "$_wav"
}
function remove_silent_section() {
local _wav_path="$1"
local _tmp="${_wav_path}.silenced.wav"
sox "$_wav_path" "$_tmp" vad
mv -f "$_tmp" "$_wav_path"
}
function create_preview() {
local _wav_path="$1"
local _preview_path="$2"
ffmpeg \
-i "$_wav_path" \
-t 10 \
-vn -ab 160k -acodec libvorbis -f ogg \
-loglevel warning \
"$_preview_path"
}
function find_bms_files() {
local _bms_dir="$1"
find "$_bms_dir" -name '*.bme' -o -name '*.bms' -o -name '*.bml'
}
# https://github.com/exch-bms2/beatoraja/issues/400
function find_preview_files() {
local _bms_dir="$1"
find "$_bms_dir" -name 'preview*.wav' -o -name 'preview*.ogg'
}
function bms2preview() {
local _bms_dir="$1"
local _tmp_wav="${_bms_dir}/tmp.wav"
local _preview_path="${_bms_dir}/preview_music.ogg"
local _bms
_bms="$(find_bms_files "$_bms_dir" | head -n1)"
if [[ -z "$_bms" ]]; then
echo "BMS file was not found: ${_bms_dir}"
exit 1
fi
if [[ -n "$(find_preview_files "$_bms_dir")" ]]; then
echo "A preview file is already exists"
exit
fi
echo "convert BMS files into a wav file: ${_bms_dir}"
bms2wav "$_bms" "$_tmp_wav"
echo "remove a silent section from the wav file: ${_bms_dir}"
remove_silent_section "$_tmp_wav"
echo "create a preview file from the wav file: ${_bms_dir}"
create_preview "$_tmp_wav" "$_preview_path"
rm "$_tmp_wav"
}
target_dir="$1"
if [[ -z "$target_dir" ]]; then
echo "BMS directory's path should be passed"
exit 1
fi
if [[ ! -d "$target_dir" ]]; then
echo "The path does not exist: ${target_dir}"
exit 1
fi
echo "start: ${target_dir}"
bms2preview "$target_dir"
echo "end: ${target_dir}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment