[Astro] #180 ブラウザだけで動く音声カッター — 曲を切ってつないで、MP3・M4A・FLAC で書き出す

[Astro] #180 ブラウザだけで動く音声カッター — 曲を切ってつないで、MP3・M4A・FLAC で書き出す

はじめに

前回は、音楽ファイルのタグエディタを作りました。

今回は、音声ファイルを切ってつないで、書き出すツールです。

じつは、同じ種類のツールを、前に途中まで作って、放置していました。MP3 専用で、機能も足りませんでした。それを、ほとんど作り直しました。MP3 だけでなくなったので、名前も Audio Cutter に変えています。

ファイルは、サーバーに送られません。

画面

全体

左に素材の一覧とタグ、真ん中に波形、右にクリップの設定です。MP3 と AAC のように、形式の違うファイルも、1 本に並べられます。

Audio Cutter の全体。MP3 と AAC を並べた波形、左に素材、右にクリップの設定

右クリック

波形の上で右クリックすると、その位置で分割したり、そこから前や後ろを消したり、無音を入れたりできます。

波形の右クリックメニュー。ここで分割、ここから前を削除、ここに無音を入れる、など

編集

MP3とAACの異なるファイルを繋いで編集。

MP3とAACの異なるファイルを繋いで編集

書き出し

形式は、「いまの形式のまま(再エンコードなし)」、MP3、M4A、Opus、FLAC、WAV(16bit・24bit)から選びます。

書き出しの画面。形式の一覧に、いまの形式のまま、MP3、M4A、Opus、FLAC、WAV

F1 ヘルプ

F1 キーで、「やりたいこと → やり方」を検索できます。動画エディタ、タグエディタと同じ作りです。普段の画面には、よく使うものだけを置いて、細かいことはヘルプに入れています。

F1 ヘルプ F1 ヘルプ

作ったもの

  • 読み込みは、MP3、M4A(AAC)、WAV、OGG、FLAC、Opus です。MP4、WebM などの動画ファイルからは、音だけ取り出します
  • 波形の上をドラッグして範囲を選び、Delete で消すと、後ろが自動で詰まります
  • 分割(S)、ここから前を消す(Q)、ここから後ろを消す(W)、選んだ範囲だけ残す(Enter)
  • クリップの頭をドラッグして並べ替え、端をドラッグして長さを変える
  • クリップごとの音量(dB)、フェードイン、フェードアウト。複製、無音を入れる、無音を削る
  • 元に戻す、やり直し。ズーム、スナップ。保存していない変更があると、閉じる時に警告が出ます
  • 再生は、全体、選んだ範囲、繰り返しに対応しています
  • 書き出しは、MP3(128〜320kbps)、M4A(AAC)、Opus、FLAC、WAV。音量をそろえる(最大音量を −1dB に)、元のタグとジャケット画像の引き継ぎもあります

作り方

1 本のトラックだけにした

素材は、1 本の連続したトラックとして扱います。クリップを並べるだけで、重ねる(ミックスする)ことはできません。何かを消すと、後ろが詰まります。

重ねられないのは、制限です。ただ、やりたいことは、曲を切って、つないで、書き出すことでした。重ねる機能を入れると、画面も操作も、複雑になります。普段の画面を、簡単なままにしたかったので、重ねる機能は入れていません。

読み込みと書き出しは Mediabunny

読み込みと書き出しには、Mediabunny(バージョン 1.61.6)を使っています。ブラウザの WebCodecs の上で動くライブラリで、形式ごとの解析や、書き出しの仕組みが、まとまっています。

  • ブラウザに標準のエンコーダがある形式は、そのまま使います
  • MP3 と FLAC は、標準のエンコーダがないブラウザのために、WASM のエンコーダを、必要な時だけ読み込みます

ライブラリは、サイトの中(public/tool/audio-cutter/vendor/)に置いています。外のサーバーからは読み込みません。ライセンスは MPL-2.0 なので、ライセンスのファイルも同じ場所に置きました。

つなぎ目のプチノイズ

別々の場所を、そのままつなぐと、つなぎ目で波形が飛んで、「プチッ」というノイズが出ることがあります。

そこで、つなぎ目の前後に、ごく短いフェード(初期値は 5 ミリ秒)を、自動で付けています。右の「全体」のタブで、長さを変えられます。

自前のリサンプラ

書き出しで、問題が出ました。

素材によって、サンプルレート(44.1kHz と 48kHz など)や、チャンネル数(モノラルとステレオ)が違います。ところが、Mediabunny の AudioSampleSource は、途中でサンプルレートやチャンネル数が変わると、エラーになります。自動では、変換してくれません。

そこで、次の 2 つを自分で書きました。

  • チャンネル数の変換(モノラルをステレオに、ステレオをモノラルに)
  • サンプルレートの変換(窓関数付きの sinc 補間。窓は Blackman-Harris、片側 8 ゼロ交差)

書き出すレートと、チャンネル数は、先頭の素材に合わせます。ダイアログで、変えることもできます。変換後の周波数が合っていることは、FFT で確認しました。

無劣化の書き出し

「いまの形式のまま」を選ぶと、再エンコードしないで、圧縮されたデータのまま、切ってつなぎます。速くて、音質も変わりません。

ただし、条件があります。

  • 全部のクリップが、同じコーデック、サンプルレート、チャンネル数であること
  • 無音の挿入、音量の変更、フェードが、ないこと

条件に合わないと、そのまま書き出せないことが、エラーで分かります。

もうひとつ、制限があります。圧縮データは、決まった長さの単位(MP3 は約 0.026 秒、など)に分かれています。無劣化で切ると、切れ目が、その単位にずれます。ずれは、約 0.02〜0.03 秒でした。ぴったり切りたい時は、再エンコードで書き出します。

音量をそろえる

2 回に分けて処理します。1 回目で、全体の最大音量を調べて、2 回目で、最大音量が −1dB になるように、音量を掛けます。上げられるのは、最大で +24dB です。

書き出した WAV で、最大音量が 0.891(−1dB)になっていることを確認しました。

最初、確認した時は、一部の区間で、最大音量が 1.25 と出て、おかしいと思いました。でも、これは、確認に使ったスクリプトが、ステレオをモノラルに混ぜて読んでいたための、見かけの数字でした。左右別に読み直すと、正しく、0.891 でした。

実機で確認できたこと

Windows 11 の Chrome で、確認しました。

  • MP3 と、48 分の AAC(M4A)を、読み込んで、1 本に並べられました
  • 波形の表示、ドラッグでの並べ替え、右クリックのメニューは、動きました
  • 書き出したファイルを、Windows のメディアプレーヤーで再生できました。タイトル、アーティスト、アルバム、ジャケット画像も、引き継がれていました
書き出したファイルをメディアプレーヤーで再生。タイトル、アーティスト、ジャケットが見える

ヘッドレスブラウザ(画面なしのテスト環境)では、次のことを確認しました。ただし、このテスト環境には AAC のデコーダとエンコーダがないので、AAC は、ここでは試せていません。

  • 読み込み:MP3、WAV、FLAC、OGG、Opus、WebM、MP4(Opus)
  • 書き出し:MP3、FLAC、WAV(16・24bit)、Opus。長さと周波数は、ffprobe と FFT で確認しました
  • 無劣化の書き出し:MP3、FLAC、OGG、Opus、WebM(Opus)。形式が混ざっている時は、エラーになりました
  • フェード、音量、無音の挿入、範囲だけの書き出し、無音を削る機能、元に戻す、やり直し

詰まったこと

元に戻すで、元の長さに戻らない

テストで、見つかりました。「無音を削る」を実行したあとで、元に戻すと、削る前の長さではなく、削ったあとの 1 つ目のクリップの長さに戻りました。

原因は、処理の順番でした。「元に戻す」用の記録を取る前に、クリップの値を、書き換えていました。記録が、書き換えたあとの値になっていたので、戻しても、戻りませんでした。書き換える前に、クリップのコピーを作るように、直しました。

ほかの編集(分割、削除、移動、音量など)は、記録を取ってから書き換えているので、同じ問題は、ありませんでした。

切ったあとの位置が、古いまま

もうひとつは、範囲を削ったあとに、クリップの位置の計算が、削る前のままになっていたことです。位置の計算の結果を、覚えておく仕組みがあって、削ったあとに、消していませんでした。消すように、直しました。

未確認のこと・制限

  • M4A(AAC)への書き出しは、実機で確認できていません。 読み込みは、実機で確認できました。書き出しは、確認したファイルが、M4A かどうかを、はっきり言えないので、未確認としておきます
  • Safari と Firefox では、確かめていません
  • 数百 MB のような、大きなファイルは、確かめていません。書き出しの時間とメモリの量が、どのくらいになるかは、分かっていません
  • 保存先をダイアログで選ぶ方法(showSaveFilePicker)は、本物のダイアログでは、試していません。使えない環境では、メモリ上で作って、ダウンロードします
  • スナップ、端をドラッグして長さを変える操作は、実機で見ていません。スマホやタブレットでの操作も、確かめていません
  • 重ねる(ミックスする)ことは、できません
  • 無劣化の書き出しは、条件が合わないとできません。切れ目も、約 0.02〜0.03 秒ずれます
  • MP3 の再エンコードは、ブラウザに標準のエンコーダがないと、WASM を使うので、長い曲では、時間がかかります

おわりに

最初は、前に作った MP3 専用のツールを、直すだけのつもりでした。でも、形式を増やそうとすると、サンプルレートとチャンネル数の違いを、自分で吸収する必要があって、結局、作り直しになりました。

実機で動かして、AAC の読み込みも、並べ替えも、書き出したファイルの再生も、動いていました。テスト環境では、試せない部分があるので、実機で確認できたのは、助かりました。

今は、v1 です。M4A への書き出しや、大きなファイルは、これから確かめていきます。