アプリにMPDFを組み込む
MPDFは標準のPDF添付ファイルで音楽情報を運びます。基本フォーマットと任意の拡張を分けて実装すれば、既存のPDF表示はそのままに再生機能を追加できます。
基本フォーマット: mpdf.json
PDFのEmbeddedFiles名前ツリーからmpdf.jsonを読み込みます。MPDF 1.xの基本フォーマットは、トラック、ページキュー、再生オプションを記述します。埋め込み音源は別のPDF添付で、次の形式で参照されます:file:。
{
"mpdf": "1.0",
"title": "Practice score",
"tracks": [
{ "id": "backing", "title": "Backing track", "src": "file:backing.m4a", "start": 10, "end": 70 }
],
"cues": [ { "page": 1, "track": "backing", "at": 10 } ],
"options": { "autoplay": false, "followPage": false, "loop": false }
}ページは1から数えます。startとendは元の録音での秒数です。キューのatも同じ元録音の絶対時間を使います。この例では、at: 10は元の録音の10秒目を意味します。任意のtimeMarkers.secondsはトラックの開始からの相対時間です。
任意の拡張: 読み取って保持する
| データ | 用途 |
|---|---|
buttons | ページ上の再生ボタンの位置とトラック参照 |
timeMarkers | ページ上の位置とトラック内の相対時間 |
seetogether-mpdf.json | SEETOの制作メタデータ、再生の選択肢、作成者の申告、共有状態 |
seetogether-score.json | 含まれるCopy Noteの楽譜・コード再生データ |
| 編集用の元データと書き込みの添付 | 作成者のリビジョン用資料(公開共有用コピーからは除外) |
これらの拡張は基本的なMPDF再生には必要ありません。読み込むときは未対応のフィールドを無視し、編集するときは保持してください。変更していないオリジナルをダウンロードさせるときは、PDFを書き換えずに元のバイトを返してください。共有用コピーは、受け取る人向けのデータだけを残す、明示的な別の書き出しです。
読み込みと再生
const pdf = await pdfjsLib.getDocument({ data: bytes.slice() }).promise
const attachments = (await pdf.getAttachments()) || {}
const raw = attachments['mpdf.json']
if (raw) {
const manifest = JSON.parse(new TextDecoder().decode(raw.content))
// Validate version, size limits, unique IDs, page ranges and track references.
// Render text with textContent, never as HTML. Keep unknown extension fields.
// Resolve file: names against attachments; never treat them as filesystem paths.
// Retain `bytes` for an unchanged download; rewriting changes the file hash.
}- 再生:
youtube:は表示した公式プレーヤーで、file:は対応するPDF添付で、https:は有効な外部音声URLで再生します。外部再生はサーバーのCORS、形式、アクセス設定に左右されます。 - ユーザーの操作前に自動再生しないでください。ページに合わせる設定は読み手の選択に従います。キューのないページでは現在のトラックの再生を続けます。
- ボタンとマーカーはPDFページを書き換えず、別の操作レイヤーとして表示してください。プレーヤーは折りたためるようにするか、楽譜の領域の外に置いてください。
- Unicodeのファイル名は保持しつつ、パスや予約されたメタデータ名を音源として扱うことは拒否してください。サイズ、ページ範囲、時間、ID、参照を検証してください。
新しいMPDFを作る
from pypdf import PdfWriter
import json
# Create a NEW MPDF from a plain PDF; do not overwrite the input.
w = PdfWriter(clone_from="score.pdf")
w.add_attachment("mpdf.json", json.dumps(manifest).encode("utf-8"))
w.add_attachment("backing.m4a", audio_bytes)
w.write("score-with-music.pdf")通常のPDFから新しいファイルを作る最小の例です。既存のMPDFを編集するには、名前ツリー、未知の添付、拡張の扱いも必要です。リポジトリのJavaScriptとPythonの基本リファレンスは、ウェブサイトの互換レイヤーとは別のものです:site/mpdf-browser.js。
作成者の申告は所有の証明ではありません
SEETOの作成者リビジョンは、匿名でないアカウントとファイル全体のSHA-256を使います。変更できない登録簿のファイルハッシュ、公開ID、所有者UIDがすべて一致する必要があります。埋め込まれたcreatorUIDだけで編集を許可してはいけません。sharedReadOnly: trueは作成者本人にとっても読み取り専用です。登録済みの作成者オリジナルを提供する前に、確定したファイルを登録してください。
公開リンクは別のサービスです
このウェブサイトのCloudflare Pages Functionsが共有用PDFを保存します。埋め込み音源、編集用の元データ、未対応の添付は拒否し、作成から90日でリンクの提供を停止します。このホスティングの方針とSEETOアカウント連携は、MPDF基本フォーマットの必須要素ではありません。
コードはMITライセンス、仕様の文章はCC BY 4.0です。技術的な提案はGitHub Issuesへ、非公開の資料や削除の依頼はサポートのメールへお送りください。