音声チャプターをPodcasting 2.0 JSONに整形
0秒、120秒、1800秒から始まる3つのチャプターが、アプリが目次表示や頭出しに使う1つのファイルになります。開始時刻は必ず前に進む必要があり、そうでなければ書き出されません。ブラウザで無料で使えます。
- 無料
- ブラウザで動作
- 登録不要
- データは端末の外に出ません
無料で実行
処理はブラウザ内で完結します。ファイルは送信されません。無料でご利用いただけます。
制作者はすでに各セクションのタイトルと開始時刻を把握しており、必要なのはcamelCaseのstartTime、任意のアートワークとディープリンク、そしてタイムスタンプが決して逆行しない保証付きの、アプリが読める正しいエクスポートです。
チャプターファイルが聴き手にもたらすもの
チャプター対応のポッドキャストアプリは、音声ファイルそのものからチャプターを読むのではありません。フィードのエピソードからリンクされた小さな別ファイルを取得し、目次の表示、各セクションへの移動、再生中の画像の切り替えに使います。各チャプターには音声の冒頭からの開始時刻(秒)が必要で、聴き手に分かりやすい名前を見せるためにタイトルも強く推奨されます。画像やリンクの追加、一覧に出さない無音チャプターの指定、終了時刻の明示もできます。アプリは再生時にファイルを取得するので、公開後でも音声を作り直さずにタイトルを直せます。
チャプターの準備と、よくある間違い
セクションを順番に、タイトルと開始する秒数を添えて書きます。たとえばイントロは0、本題は120、エンディングは1800です。ツールはこれを標準の形に変換し、安定したウェブアドレスに置ける本文を返します。よくある間違いは、開始時刻が重複したり逆戻りしたりすることです。黙って並べ替えると誤りが隠れ、別の区間に違う画像が付くおそれがあるため、ツールは並べ替えずに停止し、順序の乱れた行を知らせます。
ポッドキャストのチャプターファイルの形
Podcasting 2.0名前空間は、各エピソードをMIMEタイプapplication/json+chaptersの外部チャプターファイルへ向けます。各チャプターには少なくとも音声先頭からの秒数をfloatで表したstartTimeが必要で、聞き手が読める目次のためにtitleを強く推奨します。順序は推測ではなく検証されます。
能力は乱れた時刻を黙って並べ替えません。静かな再ソートは制作ミスを隠し、誤ったアートを誤った区間に当てる恐れがあるためです。代わりに開始時刻の厳密増加を要求し、後続行が直前と同じかより早い場合は明確に失敗します。
アプリは再生時にファイルを取得するため、公開後にタイトル修正や画像追加ができ、エピソードを再エンコードする必要はありません。
よくある質問
開始時刻が厳密増加でないとどうなりますか?
等しいまたは減少する時刻は拒否され、ポッドキャストアプリが乱れたマーカーを受け取りません。
チャプターごとに画像やリンクを付けられますか?
付けられます。各チャプターに画像と関連ページへのリンクを任意で指定でき、アプリは再生中にその画像を表示し、関連ページを開けるようにします。
チャプターをフィードに追加するには?
ツールが返したファイルを安定したウェブアドレスに置き、フィードのエピソードからチャプターファイルとしてリンクします。対応アプリは再生時にそれを取得します。
公開後にタイトルを変更できますか?
できます。アプリは再生時にチャプターファイルを取得するため、後からタイトルを直したり画像を加えたりして同じアドレスに置けば、音声を作り直す必要はありません。
目次に出さないチャプターは作れますか?
作れます。無音チャプターとして指定すると、アプリは目印として保持しますが、聴き手の一覧には表示しません。初期設定ではすべて一覧に出るので、隠したいものだけ変更します。
関連ツール
開発者向け — APIアクセス
このページの機能はすべてAPIからも利用できます。自社システムに組み込みたいチーム向けのセクションです。それ以外の方は上のツールをそのままお使いください。
エンドポイント
Bearerトークンで認証し、POST1回でタスクをキューに登録します。結果はWebhookまたは署名付きリンクで受け取れます。
お使いのスタックから呼び出す
curl -X POST https://api.kit.forhosting.com/audio/audio-chapter-export-format \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"chapters":[{"title":"Intro","start_time":0},{"title":"Main topic","start_time":120,"img":"https://example.com/art/main.jpg","url":"https://example.com/notes/main"},{"title":"Outro","start_time":1800}]}'const res = await fetch("https://api.kit.forhosting.com/audio/audio-chapter-export-format", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"chapters": [
{
"title": "Intro",
"start_time": 0
},
{
"title": "Main topic",
"start_time": 120,
"img": "https://example.com/art/main.jpg",
"url": "https://example.com/notes/main"
},
{
"title": "Outro",
"start_time": 1800
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/audio/audio-chapter-export-format",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"chapters": [
{
"title": "Intro",
"start_time": 0
},
{
"title": "Main topic",
"start_time": 120,
"img": "https://example.com/art/main.jpg",
"url": "https://example.com/notes/main"
},
{
"title": "Outro",
"start_time": 1800
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/audio/audio-chapter-export-format", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"chapters":[{"title":"Intro","start_time":0},{"title":"Main topic","start_time":120,"img":"https://example.com/art/main.jpg","url":"https://example.com/notes/main"},{"title":"Outro","start_time":1800}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"chapters":[{"title":"Intro","start_time":0},{"title":"Main topic","start_time":120,"img":"https://example.com/art/main.jpg","url":"https://example.com/notes/main"},{"title":"Outro","start_time":1800}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/audio/audio-chapter-export-format", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)リクエスト例
{
"chapters": [
{
"title": "Intro",
"start_time": 0
},
{
"title": "Main topic",
"start_time": 120,
"img": "https://example.com/art/main.jpg",
"url": "https://example.com/notes/main"
},
{
"title": "Outro",
"start_time": 1800
}
]
}レスポンス例
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "audio.audio_chapter_export_format",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}非同期APIです。task_idは即時に返ります。ポーリングは1秒あたり1リクエストまでです。
料金
単価はすべて公開しています。トークン換算や独自クレジットはありません。失敗したタスクは課金されません。
制限
max_mb | 200 |
max_minutes | 180 |
エラー
| HTTP | コード | 意味 |
|---|---|---|
401 | unauthorized | APIキーが無効か、指定されていません。Authorizationヘッダーを確認してください。 |
402 | insufficient_balance | 残高が不足しています。チャージ後に再度お試しください。 |
404 | unknown_type | 指定されたタスクタイプは存在しません。タイプ名を確認してください。 |
429 | rate_limited | リクエストが多すぎます。しばらく待ってから再度お試しください。 |
技術的な注記
Podcasting 2.0チャプターに対応するポッドキャストアプリは、MP3に埋め込んだチャプタータグではなく、エピソードのRSSアイテムからリンクされた小さなJSONファイルを期待します。本機能は、タイトルと秒単位の開始時刻(チャプターごとに任意の画像とURL)を並べた行を受け取り、標準のバージョン付きchaptersオブジェクトと、ホストしてpodcast:chaptersタグで参照できる整形済みjson_text文字列を出力します。開始時刻が厳密に増加していない場合はinvalid_inputで失敗し、不正なマーカーがフィードに届きません。
Podcasting 2.0チャプターJSONの形
そのファイルは必須キーversion(多くは1.2.0)とchaptersを持つJSONオブジェクトで、chaptersはstartTime昇順のマーカー配列です。任意フィールドにはセクションごとのアートのimg、関連ページやノートのurl、メタデータ専用の無音マーカー用にtocをfalseにする指定、明示的な終端のendTimeがあります。author・title・podcastName・descriptionなどのファイルレベル任意フィールドは、アプリのジャンプ動作を変えずにWebプレイヤーやアーカイブを助けます。本エクスポータは行指向の入力(各チャプターのstart_timeとtitle、任意のimgとurl)をそのcamelCase形へ写像するため、括弧を手編集したりversion文字列を忘れたりする必要がありません。得られたjson_textを安定したHTTPS URLに置き、itemにtype application/json+chaptersのpodcast:chaptersを追加してください。
入力契約・応答形・検証ルール
任意の出力キーはnullではなくキーごと省略します。chapters欠落、空title、負や非有限の時刻、開始より前の終了、500行超、厳密増加でない開始時刻などです。必須のchapters配列(少なくとも1オブジェクト)を含むJSON本体をPOSTしてください。各オブジェクトには空でない文字列のtitleと、非負の有限秒数のstart_timeが必要です(各行でstartTimeなどの別名も受け付けます)。チャプターごとの任意フィールドは空でない文字列のimgとurl、真偽値のtoc(falseは無音チャプター、trueは既定でエクスポートから省略)、そのチャプター開始以上の非負数end_timeです。ファイルレベルの任意文字列—version(既定1.2.0)、episode_title、author、podcast_name、description—は指定時にchaptersオブジェクトへコピーされます。成功時はversion、chapter_count、startTimeキーを持つPodcasting 2.0配列chapters、アップロード用の整形済みjson_text、mime_type application/json+chapters、およびauthor・title・podcast_name・description下のエピソードメタデータを返します。検証失敗はinvalid_inputを投げ課金されません。例として0・120・1800秒の3行と中間チャプターの画像・リンクは、3件のchapters配列と公開例と構造が揃ったjson_textを生みます。
決定論的チャプターエクスポータが効く場面
DAWでエピソードを仕上げる個人制作者は、表計算やショーノートにタイムスタンプを既に持っています。タイトルと秒の組だけを出す文字起こしやチャプター提案ツールは、ここに結果を流せばクライアントごとにPodcasting 2.0知識を埋め込まずにアプリ向け形式を得られます。検証失敗は残高を消費しません。音声から時刻を起こすASRチャプター生成は別製品と組み合わせ、マーカーが既知で標準準拠エクスポートだけが必要なときは本経路を使ってください。各アプリで名前空間を試行錯誤せず、正しいJSONファイルが必要です。実装はparseティアAの純粋処理のため、成功した呼び出しは公開された基本料金$0.002のみで、モデルトークンも外向きネットワークも使いません。モバイル目次UI向けにタイトルは短く、imgとurlは絶対HTTPS URLを優先し、編集のたびに整形を再実行して厳密増加を保ちます。
連携の活用例
ショーノート表から公開用チャプターへ
エピソード構成のタイトルと開始時刻の行を貼り、任意のアートリンクを加え、MP3の横に置くPodcasting 2.0のjson_textをダウンロードします。
CMS・ホスティングパイプラインでの検査
公開ジョブからAPIを呼び、podcast:chaptersのRSSタグを書く前に各エピソードのチャプター一覧が厳密増加の時刻かを検証します。
平文マーカーからアプリJSONへの橋渡し
編集ソフトや文字起こしツールのタイトル+秒出力を、JSONの括弧を手編集せずcamelCaseのstartTimeチャプターへ変換します。
技術的な質問
音声チャプターエクスポートはどの形式ですか?
Podcasting 2.0 JSONチャプターです。version文字列(既定1.2.0)、startTimeとtitle(任意でimg・url・toc・endTime)のchapters配列、MIMEタイプapplication/json+chaptersの整形済みjson_textファイルです。
チャプター画像やリンクを含められますか?
はい。各チャプターの任意文字列imgとurlがPodcasting 2.0のimg・urlフィールドになります。空文字はエクスポートから省略されます。
RSSフィードへどう添付しますか?
json_textを公開HTTPS URLに置き、エピソードitemに<podcast:chapters url="…" type="application/json+chapters" />を追加します。アプリは再生時に取得します。
音声チャプター整形の料金は?
ブラウザツールは無料です。APIは成功した呼び出しごとにKIT前払い残高から$0.002です。無効入力は課金されません。