ジンジャー研究室

長めのつぶやき。難しいことは書きません。

.ogg ファイルのメタデータを読んでみた

.ogg ファイルのメタデータを確認する作業が発生したので、ブラウザでディレクトリ内の .ogg ファイルのリストを読めるようにしてみた(TypeScript)。

背景

友達のゲームに BGM を提供しました。

ゲームに使用する ogg ファイルにループ位置指定のためのメタデータを埋め込むんだけど、どのファイルにメタデータを入れたのかが分からなくなるのと、変数名のタイポが不安だったので一覧でさっと確認したくなった。というのが経緯。

ちなみに、仕様は RPG ツクールのを踏襲しているらしいので、多分同じことで困っている人は多いはず。まあ欲を言えば音量レベルが揃ってるか等も知りたいけど、時間がなかったので今回はメタデータのみ読めれば OK ということに。

作ったもの

コード

GitHub - jinjor/ogg-vorbis-experiment

こんな風に読める。

f:id:jinjor:20191215230025p:plain

ディレクトリを読みたい

Native File System API が必要で Chromium でフラグを立てたりしないといけないんだけど、今回の趣旨ではないので省略。

Ogg Vorbis を読みたい

公式に vorbis-tools というツール(コマンドは vorbiscomment)が提供されているので、 CLI で済ませたい場合はこれで出来る(Mac なら brew インストールできる)。

GitHub - xiph/vorbis-tools: Command-line tools for creating and playing Ogg Vorbis files.

npm にも .ogg 読むパッケージあるよね絶対。うん、あった。 でもそれじゃつまらないので、折角だから仕様を理解してバイナリを読むことにする。

Xiph.org: Ogg

仕様はここから読めるので、サクッと Google 翻訳して読む。最近は翻訳の精度が良いので下手に自力で読むよりも母国語の方が速く読める(英語が得意なら別)。たまにテクニカルタームが翻訳されてしまうので、そこだけ原文を確認する。

Ogg コンテナを剥がしたい

実は Ogg はパケットを伝送するためのコンテナなので、Vorbis がコーデック本体。なので Vorbis 以外にも Opus とか別のフォーマットのデータが入ってるかもしれないし、音声じゃなくてもストリーミングしたいものならなんでも可能とのこと。

というわけで、 Vorbis を読むにはまず Ogg コンテナを剥がす必要がある。

以下に現時点での浅い理解を図示してみる。(間違ってるかもしれないけど、何も情報ないよりは取っ掛かりとして良いはず。ちゃんと知りたい人は公式ドキュメントを読んでください。思想とかも書いてあるので。)

f:id:jinjor:20191220004908p:plain

Page 単位でパケット列が送られる。パケットは内部的にいくつかのセグメントに分けられる(255 バイトずつ+最後は余り)。1つのパケットは複数のページにまたがることもある。多重化も考慮されていてページごとにストリームの番号が振られている。

コンテナを剥がすと上のレイヤー(上の図の2番目の帯)では、単にパケット列として読めばいい。カプセル化されていて、ちょうど TCP と HTTP みたいな関係。

Vorbis を読みたい

1~3 パケット目がヘッダーで、 1 パケット目にチャンネル数やビットレート、 2 パケット目にコメントの類が入ってる。今回読みたかったのは、 2 パケット目にある任意のユーザーコメント(LOOPSTART, LOOPLENGTH)です。まあここは単にバイナリを読むだけなので、特に図とか解説とかは必要なさそう。

今回の要件はここまでで十分なので、 3 パケット目以降はまだ読んでません。

感想など

バイナリを読むのは楽しい。

そのうちコーデックにも手を出したい。ツールを使うとクオリティ 0 ~ 1 みたいなざっくりした表示しかないので何をしてるのか良く分からないし、再エンコードした時に無駄に音質劣化していないか不安で眠れない。あと Vorbis よりも Opus の方が音質が良さそうなので、そっちも使う機会があるといいなぁという感じ。