FFmpeg を用いて Mixbook のデータ API からムービーを再構築する

2026/05/24 9:31

FFmpeg を用いて Mixbook のデータ API からムービーを再構築する

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

本稿の核心メッセージは、開発者が Mixbook のシステムを逆方向に解析することに成功し、アニメーションされたプロジェクト動画を独立した MP4 ファイルとしてダウンロードできるようにした点にある。これにより、ユーザーは自身のデジタル記憶に対してローカルの所有権を取得できる。Mixbook は動画ファイルを直接提供するのではなく、React アーキテクチャを採用しており、JSON 源からデータをストリーミングし、ブラウザ上でアニメーションを描画している。エンジニアたちは、「Memory Explorer」API を通じてこの内部データを抽出し、FFmpeg や Python スクリプトなどのツールを活用することで、これらの映画を忠実に再現した。モーション、音楽、テキストのすべてを正確に複製することができた。再構築プロセスは 4 つの段階を経て進化したが、それは以下の通りである:V1 ではクロスフェードスライドショーを作成し、V2 ではアップスケールを適用してケン・バーンズ効果を付与し、V3 ではフォントフィルターによる制限に対処するために PNG レンダリングを用いてイントロ/アウトロのテキストを復元し、V4 ではスライドショーのリズムに合わせるためにタイトルタイミングを調整した。最終的な出力は、モーションとテキストが概ね適切であるものの、技術的な課題によりフレームごとのベクター easing や正確なオリジナルタイポグラフィには欠ける 4K MP4 である。その結果、ピクセル単位の完全に同一の複製を得るためにはスクリーンレコーディングという手法だけが唯一の方法となる。このブレイクスルーは、プラットフォーム側がダウンロードを阻止することを意図した設計選択を回避するものであり、ユーザーにより良いメディアコントロールを提供しつつ、直接ファイルアクセスなしでロウなアニメーションアセットのエクスポートにおける現状の限界も浮き彫りにしている。

本文

MixBook 動画ファイルをダウンロードできない時の逆算術:JSON データから再構築する完全ガイド

MixBook 上でアニメーションプロジェクトの準備が完了しましたが、ブラウザでの再生や印刷版注文は可能で、ダウンロード機能は一切実装されていません

この状況は単なる機能制限ではなく、「レンダリング即し(オンデマンド)」アーキテクチャを採用していることを意味しています。完結した MP4 ファイルが存在せず、代わりに JSON データ構造から再生時に動的にコンポジット(合成)されているのです。

本稿では、この「ダウンロードできない」壁を突破し、リバースエンジニアリング的手法で動画を再構築するプロセスを解説します。


重要:免責事項

以下の手順は、自身の共有リンクを通じてアクセスした独自プロジェクトを対象としたメモリの回収方法についてのみ記述しています。第三者のコンテンツや外部への悪影響を与える意図は全くありません。

1. ダウンロード不能な理由と最初の行き詰まり

直感的なファイル探索では以下のように失敗します。

  • 編集用 URL は非公開
    • ログインしていない状態でアクセスすると
      403 Forbidden
      を返します。
    https://www.mixbook.com/memories/edit?pid=123456 → 403 エラー
    
  • 共有プレビュー URL にも動画ファイルなし
    • 視聴用キー(
      vk
      )を付与したプレビューリンクでは、HTML のみ返ってきます。生 HTML に
      .mp4
      videoUrl
      は含まれません。
    https://www.mixbook.com/memories/preview?pid=123456&vk=YOUR_VIEW_KEY → 純粋な HTML ページ(約 110KB)
    

ページ自体は正常に読み込まれますが、これは JavaScript アプリケーションのシェル に過ぎず、動画データはクライアントサイドで構築されているためです。

2. レア・エンハンスメント:独立した Next.js アプリへのアクセス

プレビューページの埋め込み設定から、以下のサービスホストが確認できました。

{ "baseUrl": "https://memories.mixbook.com" }

これらは MixBook メインサイトとは異なるドメインで、実際のルートに到達できます:

https://memories.mixbook.com/memories/preview?pid=123456&vk=... → 200 OK

このリクエストには React サーバーコンポーネントのペイロードが含まれており、そこから

AnimatedProject
というコンポーネントが特定されました。このコンポーネントは独自にデータをフェッチします。

3. API エンドポイントの特定

Next.js バundles の検索(grep)により、データ取得ロジックのソースコードが見付かりました。

// Redux Toolkit async thunk の一部
let h = (0, n.hg)("animatedProject/fetchAnimatedProject", async (t, e) => {
    let { projectId: i, viewKey: n } = t,
        a = o().auth.token,
        u = "".concat(s.l.apiBaseUrl, "/api/v2/my/animated_projects/").concat(i);
    return n && (u += "?".concat(new URLSearchParams({ vk: n }))),
        (await r.L.get(u, { token: a })).data.data;
});

より:

  • API エンドポイント
    {apiBaseUrl}/api/v2/my/animated_projects/{projectId}?vk={viewKey}
    
  • 呼び出しテスト(cURL)
    curl -s "https://www.mixbook.com/api/v2/my/animated_projects/123456?vk=YOUR_VIEW_KEY"
    

これにより、約 174 KB の JSON データが返され、動画の「定義」が取得できました。

4. 動画の真の構造:コンポジットされたメディア

API は完成済み動画を返すのではなく、再生に必要な定義データのみを返します。

  • プロジェクト定義

    data
    ├── name: "Our Trip to the Coast"
    ├── durationInFrames: 2598.96      # 24fps で約 108.3 秒
    ├── musicTrack                      # オーディオファイル URL (S3)
    ├── segments: [ 43 items ]          # セグメントリスト(動画単位)
    └── transitions: [ 42 items ]       # トランジションリスト
    
  • 各セグメントの内容

    • Lottie ベクターアニメーション (
      1920x1080, 24fps
      )
    • フォン assets に写真(
      photo
      )やコンポジットレイヤーが含まれます。
    • 写真 URL: S3/CDN で公開されています。

結論:サーバー上には MP4 ファイルは存在しません。 ダウンロードすべきものはないため、ブラウザの「再生」動作を真似て自分で再構築するしかありません。

5. 素材抽出スクリプト

必要な情報はすべて API から取得可能です。以下の Python スクリプトで写真と音楽のリストを作成します。

import requests
import json

# データ取得
data = requests.get("YOUR_API_URL", params={"vk": "YOUR_VIEW_KEY"}).json()
segments = data["data"]["segments"]

photos = []
for s in segments:
    for a in s["lottieAnimation"].get("assets", []):
        # 写真タイプのみ収集
        if a.get("meta", {}).get("type") == "photo" and a["p"].startswith("http"):
            photos.append(a["p"])

print(f"{len(photos)} 枚の写真と音楽トラックを収集しました。")

6. 再構築プロセス v1~v4

Stage 1: スライドショーの時間計算(クロスフェード)

108.3 秒という目標時間で、42 枚の写真を表示するには、以下の算術が必要です。

  • パラメータ
    • N
      (写真数): 42
    • T
      (トランジション時間/重なり): 0.8 秒
    • TOTAL
      (目標時間): 108.3 秒
  • 計算式
    D = (TOTAL + (N - 1) * T) / N        # 各写真あたりの表示時間(約 3.36 秒)
    step = D - T                          # クリップの移動量(約 2.56 秒)
    

FFmpeg スクリプト構成:

  • 写真を
    1920x1080
    にスケール・ノーマライズ。
  • xfade
    フィルタを連鎖させ、
    step
    でオフセットを調整。
  • 音楽トラックに合わせてフェードアウト。

Stage 2: ケンバーンズ効果(Ken Burns Effect)の適用

静止画に「生き気」を持たせるには、FFmpeg の

zoompan
フィルターを使用します。

  • ジッター回避
    • 単なる
      zoompan
      はカクつきが発生するため、
      select='eq(n\,0)'
      最初のフレームのみを読み込ませ、そこから滑らかに動きを生成させます。
  • アップスケール
    • ズーム前の写真を 4K にアップスケーリングしておくことで、クロップしてもシャープな画像を保ちます。
  • アニメーションの制御
    select='eq(n\,0)',       # 入力フレームを最初の 1 フレームに固定
    zoompan=z='...':x='...':y='...':d=101:s=1920x1080:fps=30   # d を全フレーム数(約 101)に設定
    

Stage 3: テキストとタイトルカードの復元

API レスポンスから抽出されたテキスト(イントロ、アウトロ)を表示するには、

ffmpeg drawtext
は利用できないため別のアプローチを取ります。

  • フォントの問題
    • MixBook の独自フォント(Proxima Nova)がない場合、
      Arial Bold
      などを使用します。
  • 描画手法:PNG コンポジット
    • Python
      Pillow
      でテキストとドロップシャドウを含む透過 PNG を作成。
    • FFmpeg 上で
      overlay
      フィルタで合成。
    [1:v]fade=t=in:st=0.3:d=0.5:alpha=1,fade=t=out:st=2.0:d=0.5:alpha=1[ti];
    [0:v][ti]overlay=0:0:enable='between(t,0.2,2.6)'[v1];
    

Stage 4: タイミングの微調整

元ネタのタイトル表示時間は 5 秒ですが、実際の再構築ではスライドショーのペースに同期させる必要があります

  • 解決策
    • タイトルフェードアウト時間を
      step
      (約 2.56 秒) より短く設定し、次の写真がクロスフェード入りする直前に消えます。
    "[1:v]fade=t=in:st=0.3:d=0.5:alpha=1,fade=t=out:st=2.0:d=0.5:alpha=1[ti]"
    

7. 再現可能か?の比較表

要素再現度備考
写真、順序、タイミング✅ 完璧API から直接取得・制御可能
音楽+エンディングフェード✅ 完全オリジナル音声ファイル使用
クロスフェード効果✅ 実現可能
xfade
フィルタを使用
ケンバーンズ動き⚠️ 近似値正確なキーフレームではないが滑らかな実装
タイトル+オウトラードテキスト✅ 実現可能フォント代用、シンプルフェード処理
厳密な Lottie アニメーション❌ 不可能ブラウザ内でのレンダリング動作は再現不可

8. まとめと教訓

MixBook の「機能欠落」は、実はデータ駆動型・オンデマンド型アーキテクチャを示しています。

  1. ページにファイルがなくても、アプリを読み解け。
    • クライアントバundles を検索し、
      animatedProject
      という関数名から API の存在を特定しました。
  2. 「ダウンロード不可」は「コンポジット可能」の裏返し。
    • JSON デフォニションさえ取得できれば、同じ環境で再構築できます。
  3. API をインターフェースとして扱い、欠落部分を自分で補完せよ。
    • drawtext
      が使えないなら Pillow で描画し、オーバーレイ処理を行うなど、手段は無限に広がります。

このようにして午後間もなく、動き・音楽・タイトルを全て備えた 1080p MP4 ファイルが手元に生まれました。MixBook が提供しなかった「ダウンロード機能」は、私自身が構築したのです。

同じ日のほかのニュース

一覧に戻る →

2026/05/28 5:00

YouTube が AI 生成動画を自動でラベル付け

## Japanese Translation: 2026 年 5 月現在、YouTube は視聴者に対する AI 生成コンテンツに関する即座の明確化を確保するため、AI デイスクロージャーシステムを大幅に見直しています。最も重要な更新は、フォトリアリスティックまたは意味のある変改が行われたメディアについては動画プレーヤーの直下にラベルを顕著に表示し、Shorts では説明にのみ埋め込むのではなく、オーバーレイでラベルを表示することです。非現実的、アニメーション、または軽微な変更が加えられたコンテンツについては、開示は引き続き拡張された説明に維持されます。この統合的なラベルリング基準は、2024 年以降増大するコミュニティの透明性への要請に応えるため、すべての此类の重大な AI 生成または変更されたメディアに適用されます。 特に重要なのは、AI ツールの使用がクリエイター収益化能力やプラットフォーム上の推奨受容に影響を与えることのないことです。具体的には、開示ラベルは動画の推奨か収益化資格への影響を及ぼしません。本ポリシーは、Veo や Dream Screen といった YouTube 自前のツールで作成されたコンテンツと、C2PA メタデータでマークされたサードパーティ製素材を区別しており、これら両方とも恒久的な開示ラベルが付与されます。以前クリエイターは自主的な開示に依存していましたが、現在は重大な AI 機能の検出がある場合でも明示的なフラグがなくても自動的に行き来されることがデフォルトとなっています。今後、YouTube は内部シグナルを利用して AI マテリアルを自動的に特定し、純粋な自主的モデルから移行します。クリエイターは、作業が誤ってフラグされた場合に YouTube Studio 内でエラーを修正する権利を維持します。最終的に、この転換は業界全体の透明性を推進すると同時に、生成技術を利用する革新者に対する罰則を伴いません。

2026/05/28 1:39

Anthropic と OpenAI が商品と市場の適合性を発見したと思います

## Japanese Translation: AI 市場における主要な戦略転換として、Anthropic や OpenAI のような先導的なプロバイダーが、重いサブスクリプション割引から標準 API プライシングモデルへ移行しており、補助されたアクセス時代が終わりを告げました。この変化は、コーディングエージェントに対する製品市場適合の実現、ならびにそれらを維持するために現在必要な大規模なインフラコストによって駆動され、2025 年後半に正式化され、2026 年頭で完全に実現されました。Anthropic はエンタープライズプランを席数 20 ドルに加えての使用量モデルへ移行し、OpenAI も GPT-5.5 のリリース後、すべてのプランをトークン使用量との直接連携に合わせました。この財務的実態が鋭い企業の反応を引き起こしました:Uber は Claude Code そのものだけで年間 AI 予算を「上限」に達させ、Microsoft は内部的ツールの優先のために Anthropic ライセンスの取消を allegedly(とされ)行っています。一方、需要は依然として堅くあり、SpaceX は 2029 年までコンピューティング容量に対して月間 12.5 億ドルコミットしています。アナリストらは現在、Anthropic が 2026 年第 2 四半期に初めて利益のある四半期を迎え、API 収益が 109 億ドルに達すると予測しており、2025 年後半の楽観視から、エンタープライズグレード AI インフラを維持する高コストの実態へと根本的な調整を示しています。

2026/05/28 4:24

Apple と Google がプッシュ通知に注力する取り組みとは

## Japanese Translation: 主要なテクノロジー企業(具体的には Google、Yahoo、Microsoft、Apple)は、プッシュ通知を単なる配信チャネルから、プラットフォームがメッセージを受信する前に解析し、順位付けし、変更を加え、ユーザーに到達させるまで積極的に管理する環境へと本質的に変革させてきた。この変化により、「通知パイプ」は厳密に制御された空間へと転換しており、現在では Apple(APNs)と Google(FCM/Firebase)によって支配されており、送信側は厳しいフィルタリング、不透明な編集、そしてスロットリングや優先度低下による拒否の可能性に直面している。2009 年から 2017 年までは静脈的であったが、Android 8 の通知チャンネルと iOS のフォーカスモード導入を機にこの介入の時代が始まり、許可率を 85% から 67% に大幅に引き下げる影響をもたらした。現在では、Apple の 30 億パラメータ規模のモデルや Google の Gemini Nano といった固有モデルに基づき内容を再書き換えしたり、未発表のランキングロジックで順位付けを行ったりする独自メカニズムによって、従来のダウンストリーム指標がメッセージの抑制や改変を隠蔽するため信頼できなくなっている。その結果、開発者はクロスセルや教育コンテンツのためにプッシュ通知に依存し続けることができず、代わりにそのようなインタラクションをメトリクスが完全に可視化される自社所有の_Surface_(例:アプリ内インボックス)へと移行させる必要がある。このトレンドは、準拠しない送信者に対する「ゼロ・トレランス」ポリシーの拡大と、通知から直接自動タスクを発火させる AI エージェントの登場へと向かっており、メッセージを受動的なアラートではなく制御シグナルへと本質的に変えていく。

FFmpeg を用いて Mixbook のデータ API からムービーを再構築する | そっか~ニュース