神々を掘り返して自作プレイヤーに移植したら、最後はChromeに負けかけた話
——また人類は、1行の「何もしないコード」に救われた——
おつかれさまですぺこり
今日も今日とて、動画編集という「手作業でやると人間の尊厳が0.05秒単位で削れる苦行」をすべて機械に押し付けるべく、自作の歌詞動画(リリックビデオ)プレイヤーを開発している者です。
今回のテーマは、インターネットの海に眠る「先祖の遺産」の掘り起こし、そしてGoogle Chromeという巨大な神が仕込んできた罠との死闘の記録です。
1. 埋蔵金はAPIの奥に眠る
この界隈には、楽曲に合わせて歌詞をダイナミックに躍らせる『TextAlive Programmer』という偉大な文化圏があります。
そこには、過去の猛者(神々)が作った美しくもカオスな演出プラグインが大量に眠っているのです。
「これ、F12キー(開発者ツール)で泥臭くハッキングしなくても、API叩けば生コード引っこ抜けるのでは?」
そう気づいた私は、さっそくコマンドを叩きました。
ビンゴ。
認証すら不要で、過去の遺産(JavaScript)がドバドバ獲れます。
この時の私は「勝った。これで神々の演出を全部ハックして、我が自作プレイヤーに統合できるぞ!」と夢を見ていました。
ええ、夢を見るのは自由です。
そのあと、「他人が書いた宇宙」でお漏らしするまでは。
※規約上イケることしかやってません
2. 神殿を解体し、我が家の増築材にする
今回、自作プレイヤーの演出エフェクトを増やすべく、3本のプラグインを密輸……ゲホン、移植しました。
しかし、いざコードを開くとそこは
「一画面ですべてが完結するワンダーランド」
元プラグインは、文字の配置も、演出も、装飾も、カメラワークも、すべてひとつのコードに詰め込んだ「全部入りデラックス界王神仕様」だったのです。職人芸ですが、再利用性は壊滅的。
一方、私の自作プレイヤーは「文字配置」「装飾」「カメラ」をきっちり分ける近代的マイホーム設計。そのままでは使えません。
やるべきことは一つ。
「他人の神殿を解体し、我が家の増築材にする作業」です。
元の美しい一体感をバラバラにバラす残酷な作業。設計とは、愛のある解体なのです。
3. 最悪のバグは「なんかズレる」
こうして神々の力を手に入れた自作プレイヤーですが、テスト再生した瞬間、背筋が凍りました。
派手なエラー画面は出ない。でも、「なんかズレる」。
エンジニアにとって「エラーを吐かずに挙動だけが不気味にズレるバグ」ほど恐ろしいものはありません。
あ、エンジニアじゃなかった。
恐怖のバグ其の壱:再生した瞬間に時間が60ms跳ぶ
音楽を一時停止して、再生する。ただそれだけ。
なのに、再生ボタンを押した瞬間に、内部のタイマーが40〜60ミリ秒(約0.06秒)だけ未来へワープするのです。
0.06秒。人間の人生においては誤差です。
しかし、音楽の世界では致命傷。文字の登場が0.06秒ズレるだけで、人間は「ウッ……なんか気持ち悪い……」という強烈な違和感を抱きます。
というものの、実際は1.5秒ズレるバグもあって破滅したのですがね。
原因を調べ尽くした結果、Google Chrome(およびEdge)の心臓部にある「音楽再生の仕様(HTMLAudioElementの気まぐれ)」だと判明しました。
一時停止から復帰するとき、ブラウザ側が「よっしゃ、キリのいいバッファの位置まで時間を進めたるわ!」と余計なお世話を焼いていたのです。
「現在の時刻に、現在の時刻を代入する」
右辺と左辺が全く同じ。一見、何もしていないように見えます。虚無です。哲学です。
しかし、これで直る。
あえて「今の時間だよ!」とブラウザの耳元で大声で言い直してやることで、ブラウザがハッと正気に戻り、未来への暴走(ワープ)を止めます。
意味がわからない。だが動く。開発とは、意味がわからなくても動いたコードに敬礼する仕事です。
恐怖のバグ其の弐:上半身だけ電車に乗る文字たち
もうひとつのバグも陰湿でした。
音楽を「再生中」は歌詞とリズムが完璧に合っているのに、ボタンを「一時停止」した状態でタイムラインをマウスでゴシゴシ動かす(シークする)と、表示がガタガタにズレる。
原因は、画面を描画する処理の「手抜き」でした。
-
再生中: 文字も、背景も、カメラも、全員で一緒に時間を進める。
-
停止中: 文字だけが新しい時間に移動し、背景とカメラは「前の時間のまま」居残る。
人間で言えば、上半身だけ新幹線に飛び乗って、下半身がホームに取り残されている状態です。そりゃズレるわけだが、よくわからん。
再生中と停止中で処理のルートが分かれているコードは、片方だけ直すと必ず未来の自分を殺しに来ます。
そしてその「未来の自分」は、だいたい当日の夜遅く、眠気に襲われている頃にやってきます。
一通りタイミング修正が終わり、深い息をつく。
「しゅー...」
最初から再生して確認すると
全部ズレてて昇天することになりました。
4. 人間の尊厳を守るスライダー
地味ながら、開発者のメンタルを守る最大の機能も追加しました。
全体の文字のタイミングを「ちょっと早く」「ちょっと遅く」一括調整するボタンです。
今までは裏の黒い画面(コンソール)から呪文を打ち込まないと動かなかった機能を、画面上部に「🎯 同期」という爽やかなスライダーとしてUI化しました。
これがないと、曲ごとに「手動で1文字ずつ0.05秒ズレを直す」という地獄の強制労働が発生します。歌詞動画の手動補正とは、人間の尊厳を0.05秒単位で削る作業。ツール1つで、私は私の尊厳を守ったのです。
しかしながら、色々やってるうちにその存在すら記憶からは去った。
気付けばなんか重く重い手作業をやっている。
結論:今日のところは勝ちでいい
今回のワークフローをまとめます。
-
先祖の遺産のURLを投げる。
-
APIで生コードをもぎ取る。
-
設計をバラバラに解体する。
-
自作プレイヤーに組み込む。
-
再生する。
-
ズレる。
-
絶望する。
-
直す。
-
「なぜ直ったのか分からない1行」に涙を流して感謝する。
一見、足踏みしているようですが、進んだ先にある落とし穴に「HTMLAudioElement pause→play currentTime jumpバグ」という名前をつけ、埋め立てることに成功しました。
名前をつけて、直して、こうして記事のネタにした。なら、今日のところは人類の勝ちでいいはずです。たぶん。
しかしどうしても、タイミングがズレる。
自動でボーカル分離してタイミングを機械が自動で取ってるのに、ズレる。
わからない、神のみぞ知るのか。
そして第二弾が完成する。
ようやく演出実装フェーズに入ったかというだけのところで
とてもショボい文字
それを映像でカバーした作品となった。



