作品を「どこでも読める形」と「誰が作ったかの証明」に変える

AI で作った曲や記事、特定のアプリから取り出せますか? 作ったアプリが終わったら、データごと消える——そんな閉じ込めを避けるために、作品を「他の世界が読める形」に翻訳する道具を3つ作りました。行き(2つ)と、帰り(1つ)です。

先に、あなたにとっての得を。 この3つを使うと、手元の作品を“他の世界が読める形”に変換しておけます。今すぐ何かのサービスと繋がるわけではありませんが、後から繋ぎたくなったとき、変換し直す手間がいらない状態になります。今日から試せる一歩は、書き出した JSON-LD(JSON で書く、機械が意味を読める形式)を Schema Markup Validator(validator.schema.org)に貼り、「曲(MusicComposition)」という構造として検出されるのを確認することです(詳しくは末尾)。

  • 行き① schema.org — Google や他アプリが読める共通語に翻訳する
  • 行き② C2PA — 「誰が・いつ・どう作ったか」の証明書に翻訳する
  • 帰り:逆変換 — 翻訳先から、元の作品データに戻す

この記事では、それぞれが何なのか・何が嬉しいのか・どこまで出来て何がまだ出来ないのかを、実際の出力を見せながら説明します。専門用語は初出で必ず言い換えます。


前提:openformats は「作品の台帳」

まず土台の話です。openformats は、曲・本・ラジオ・動画などを1作品=1つのJSONファイルで持つ個人仕様です(openformats)。

JSON(ジェイソン)とは、プログラムと人間の両方が読めるテキストの箱だと思ってください。特定のアプリの専用形式ではなく、ただのテキストなので、100年後でもメモ帳で開けます。

たとえば「ひとつ先へ」という曲は、こんな情報を持っています。

{
  "kind": "music",
  "id": "hitotsu-saki-e",
  "title": "ひとつ先へ",
  "authors": [{"name": "濱田優貴"}],
  "content_hash": "bfa6ce17b33cfb69efc241bb368a02d59d3d37e9c4202158f9f9bb3b690bac78"
}

content_hash(コンテンツハッシュ)は、作品の中身から計算した指紋です。タイトル・作者・種類といった本体が1文字でも変われば、この64桁の文字列も変わります。だから「同じ作品かどうか」を一瞬で判定できます(音源ファイルは別の指紋で、署名はまた別枠で管理しています)。

問題は、この台帳を他の世界がまだ読めないことです。Google は読めないし、「この曲、本当にこの人が作ったの?」を証明する仕組みも別にあります。そこで翻訳が必要になります。


行き① schema.org — 「世界共通の名刺」に翻訳する

何なのか

schema.org(スキーマ・ドット・オルグ)は、Google・Microsoft・Yahoo が共同で作ったウェブ上の共通語彙です。「このページには曲がある」「作者は誰か」「作成日はいつか」を、検索エンジンが機械的に理解できる形で書くためのルールです。

何が嬉しいのか

作品を schema.org の形に翻訳すると、検索結果や他のアプリが、その作品を“曲として”正しく認識できます。画像のaltテキストが検索に効くのと同じで、構造化された情報は発見されやすくなります。

ただし、今すぐ Google 検索に出るわけではありません。 openformats は外部採用がまだ0件なので、現時点でこの翻訳の効果が出るのは「自分のサイトで正しく構造を出せている」ところまでです。効果が花開くのは、誰かの道具やサイトがこの形式を実際に読み始めてから。それでも、読める形で持っておくこと自体に意味があります。いざ繋ぎたくなったとき、ゼロから作り直さずに済むからです。

実際の出力

「ひとつ先へ」を翻訳すると、こうなります(読みやすさのため一部省略)。

{
  "@type": "MusicComposition",
  "name": "ひとつ先へ",
  "identifier": "hitotsu-saki-e",
  "author": [{"name": "濱田優貴"}, {"name": "Sente / 先手"}],
  "sha256": "bfa6ce17...",
  "associatedMedia": [{"contentUrl": "Hitotsu-Saki-e-yukihamada.mp3", "encodingFormat": "mp3"}]
}

@type: MusicComposition が「これは曲です」、author が作者(濱田優貴)と演奏者(Sente / 先手)の2名、associatedMedia が実際の音源ファイル(実際は3件)、という具合に、世界共通の言葉に置き換わっています。

ここに小さな限界もあります。元データでは「作者」と「演奏者」を区別していますが、schema.org に書き出すとその区別が落ちて、両方が author に入ります。往復しても役割までは戻りません。名前と並びは保てるが、役割は保てない、という制約です。

小さな工夫:additionalType

実は翻訳には落とし穴がありました。openformats には device(機器)と product(製品)という別々の種類がありますが、schema.org ではどちらも Product という同じ1つの型になってしまいます。

そのままだと、翻訳して戻したときに「機器だったものが製品になる」という事故が起きます。そこで additionalType: "openformats:music" のように元の種類を小さく書き残すようにしました。これで往復しても種類が消えません。


行き② C2PA — 「誰が作ったか」の証明書に翻訳する

何なのか

C2PA(シー・ツー・ピー・エー)は「Content Credentials」とも呼ばれ、デジタル作品の来歴を、改ざんすると分かる仕組みで証明する国際的な取り組みです。写真や動画が「どこで撮られ、誰がどう編集したか」を、後から書き換えると検出できる形で添付できます。AI生成物に「AIで作りました」と表示する動きの土台でもあります。

何が嬉しいのか

openformats はもともと、作品の中に「作者・作成日・どう作ったか・デジタル署名」を持っています。C2PA に翻訳すると、それが業界標準の証明書の形になります。ただし後述するとおり、今できているのは証明書の中身(マニフェスト)を正しく組み立てるところまでで、対応ツールがファイルから直接読める状態にするには、次の「ファイルへの埋め込み」が要ります。写真アプリで「この画像は AI 生成」とバッジが出る、あの仕組みの土台に、中身の形だけは揃った、という現在地です。

実際の出力

「ひとつ先へ」の C2PA マニフェスト(証明書の中身)はこうです(読みやすさのため大幅に省略)。

{
  "claim_generator": "Suno/v4",
  "assertions": [{"label": "c2pa.hash.data", "data": {"hash": "bfa6ce17..."}}],
  "signature_info": [{"alg": "Ed25519", "signer": "yukihamada"}]
}

読み解くとこうです(assertions=記録の項目には、他に作成履歴・AI生成の印・schema.org情報も入ります)。

  • c2pa.hash.data — 作品の指紋(改ざん検知の基準)
  • c2pa.actions — 「Suno v4 で作った」という操作の記録。trainedAlgorithmicMedia はAI生成であることを明示する印
  • signature_info — Ed25519(エド25519)という方式のデジタル署名。本人しか持てない電子印鑑で、押した本人しか作れず偽造は難しい。ただし今の実装は自分で押す「自己署名」で、第三者が身元を保証する仕組み(認証局の連鎖)は別途必要

つまり「この曲は、この指紋のこの内容で、Suno v4 を使って、この人が作った」を、機械が検証できる形で残せます。

出来ることと出来ないこと

大事な限界を書きます。今回作ったのはC2PA の「中身(マニフェスト)を JSON で書き出す」ところまでです。本来の C2PA は、その証明書を画像や音声ファイル自体に埋め込む必要があります(JUMBF や COSE という、ファイルに埋め込むための専用の入れ物。ファイルのすき間に荷札を差し込むイメージです)。

その埋め込みはまだ実装していません。今できるのは「証明書の中身を正しく組み立てる」ところまでで、「ファイルに焼き付ける」ところは次の課題です。


帰り:逆変換 — 翻訳先から元に戻す

何なのか

ここまでは「行き」でした。逆変換は、schema.org の形から元の作品データに戻す機能です。

何が嬉しいのか

一方通行の翻訳は、実は「ハブ」ではありません。あなたの側から見ると、他のツールが schema.org で持っている作品情報を、openformats の台帳に取り込める、ということです。たとえば、別のアプリが書き出した曲のメタデータを、手元の台帳に持ってこられる。今は自分の往復確認までですが、相手が現れればすぐ取り込める状態です。ようやく**双方向に“繋げられる”**土台ができました。

実際に往復させた結果

「ひとつ先へ」を schema.org に翻訳し、それを逆変換で戻すと、こうなります。

元の content_hash : bfa6ce17b33cfb69efc241bb368a02d59d3d37e9c4202158f9f9bb3b690bac78
戻した content_hash: bfa6ce17b33cfb69efc241bb368a02d59d3d37e9c4202158f9f9bb3b690bac78

ただし、この一致は「復元した中身から指紋を計算し直して同じになった」という意味ではありません。書き出すときに sha256 として指紋も一緒に保存し、戻すときにそれをそのまま戻しているからです。つまり「同じ作品として識別できる(同一性が保たれる)」ことの確認であって、復元の忠実さの証明ではありません。

本当に見るべきは、戻った中身の照合です。手元の全9作品で、タイトル・種類・作者名・作成日・音源の情報が元と一致しました(ただし作者と演奏者の「役割」の区別は戻りません)。一方で、歌詞・セクション・トラック・署名といった創作の中身や付随情報は schema.org には載らないので戻りません。

戻るもの戻らないもの
タイトル・種類・作者・作成日・言語・音源の情報歌詞・セクション・トラック・署名・制作履歴

つまり往復で保てるのは「骨格」と「同一性」までです。曲の歌詞や台本のような創作の中身は戻らない。これは正直な限界です。


3つをまとめると

変換向き何のために状態
schema.org行き検索・他アプリが読めるように実装済み・往復可
C2PA行き来歴を証明する証明書に実装済み(JSONまで)
逆変換帰り他の世界から取り込む実装済み

ブラウザだけで変換できるようにしました

ここまでの3つは、コマンド(tools/export.py)で動かすものでした。それだと「まず試す」のハードルが高いので、ブラウザだけで完結する変換ツールを作りました。

  • 変換ツール:https://yukihamada.github.io/openformats/convert.html

作品 JSON をドラッグ&ドロップするか貼り付けるだけで、schema.org(JSON-LD)・C2PA マニフェスト・逆変換(作品 JSON へ戻す)の3つを、その場で切り替えて確認できます。ダウンロードもコピーもでき、ファイルはどこにも送信しません(すべてブラウザ内で処理)。インストールもログインも要りません。

中身はコマンド版の忠実な移植です。ブラウザで計算する指紋(content_hash)が Python 版と一致するか、全107ファイルで照合するテストを追加(順方向の一致に加え、逆変換が Python 版と完全一致し content_hash を保つことまで確認)し、すべて通りました。同じ変換をサイトの「既存標準」の節からも開けます。


検証したこと

誇張しないために、実際に走らせた結果を残します。

  • テスト 35件パス(tests/test_core.py。12種類の作品タイプの往復+C2PA の回帰テストを追加)
  • ブラウザ変換ツールの出力が Python 版と一致:全107ファイル・642項目パス(node tests/convert.test.mjs)
  • スキーマ検証 不整合0件(.venv/bin/python tools/validate.py --all)
  • 全9作品の verify(指紋・音源の実体一致)が すべて true。署名検証も 8作品で true(動画1作品は未署名)
  • 本番サイト https://yukihamada.github.io/openformats/ と変換ツール convert.html は HTTP 200

試すときはこうです。まずリポジトリを clone して中に入り、--out-dir で書き出してから、そのファイルをそのまま逆変換に渡すと往復できます。

git clone https://github.com/yukihamada/openformats && cd openformats

# 書き出し(schema.org / C2PA の2種類)
python3 tools/export.py schema.org works/hitotsu-saki-e.music.json --out-dir /tmp/of
python3 tools/export.py c2pa       works/hitotsu-saki-e.music.json --out-dir /tmp/of

# 逆変換(書き出した schema.org ファイルをそのまま渡す)
python3 tools/export.py import /tmp/of/hitotsu-saki-e.music.schemaorg.json

この手順で戻した content_hash が元と一致することを、全9作品で確認しています。

明日あなたができる小さな一歩:書き出した schema.org の JSON-LD を、Schema Markup Validator(validator.schema.org)に貼ってみてください(サイトが無ければコードを直接貼るだけでも確認できます)。少なくとも「これは曲(MusicComposition)で、作者は誰か」という構造を機械が検出したことを、その場で確認できます(MusicComposition は Google の強調表示いわゆるリッチリザルトの対象ではないので、そこは別の話です)。外部採用を待たずに、今日から試せる得です。


まだ足りないもの(現在地)

openformats は外部採用がまだ0件の個人仕様です。今回の3つの変換で「ハブ」の実体はできましたが、名実ともに標準になるには、実際に誰かの道具がこの形式を読み書きしてくれる必要があります。

次にやるべきは、変換先を増やすことより、最初の1人に使ってもらうこと。C2PA のバイナリ埋め込みも、その次の課題です。

openformats を使わない人にも、持ち帰れるもの

もしあなたが自分のデータ設計をしているなら、今回の2つの工夫はそのまま流用できます。

  • 元の種類を小さく書き残す:翻訳先で型が潰れても additionalType に元の種類を残せば、往復で種類が消えない
  • 指紋で同一性を判定する:本体から content_hash を計算し、本体が変わっていないことを一瞬で確かめる(音源や署名は別管理)

標準に採用されるかは分かりませんが、この考え方自体は今日から自分のデータに使えます。