ドキュメントNode.js SDKの使い方

Node.js SDKの使い方

@transcript1/sdkで、サーバーから動画リンクやローカルファイルを文字起こしします。テキスト・字幕の取得、進捗の監視、エラー処理を説明します。

TypeScriptやJavaScriptのサーバーから文字起こしするには、@transcript1/sdkを使います。ファイルのアップロードから完了待ち、文字起こしの取得までSDKで行えます。

SNSリンクには、SDKの1.1.0以降が必要です。1.0.1はYouTubeにしか対応しておらず、それ以外のリンクはAPIへの送信前にエラーになります。npm i @transcript1/sdk@latestで更新してください。

1.1.0では、YouTubeに加えてX、TikTok、Instagram、Facebook、Blueskyのリンクを扱えます。Twitch、Dailymotion、Pinterest、LinkedIn、Snapchatには、それぞれに対応したリリースを使ってください。古いSDKでは、リンクをAPIに送信する前に拒否することがあります。

インストール

npm i @transcript1/sdk

以下のコード例はESモジュールです。.mjsで保存するか、package.jsonに"type": "module"を設定して.jsで保存してください。Node 20.19以降なら、require('@transcript1/sdk')のようにrequire()でも読み込めます。

APIキーを設定する

「API keys」でキーを作成します。サーバーの環境変数TRANSCRIPT1_API_KEYに設定するか、インスタンスの作成時にapiKeyで渡してください。

import { Transcript1 } from '@transcript1/sdk';
 
const t1 = new Transcript1(); // reads TRANSCRIPT1_API_KEY
const other = new Transcript1({ apiKey: 't1_...' });

キーを設定しないと、コンストラクターがTranscript1Errorをスローします。エラーコードはmissing_api_keyです。

文字起こしを実行する

transcribe(input, options)は、ジョブを作成して完了まで待ちます。成功すると、status: 'completed'とtranscriptフィールドを持つCompletedTranscriptionを返します。ジョブが失敗した場合やキャンセルされた場合、Promiseはrejectされます。

const done = await t1.transcribe('https://youtu.be/dQw4w9WgXcQ');
console.log(done.transcript.text);
 
const file = await t1.transcribe('./interview.m4a', { speakers: true });

BufferやUint8Arrayを渡すときは、filenameも指定してください。SDKはファイル名からメディアの種類を判定します。

import { readFile } from 'node:fs/promises';
 
const buffer = await readFile('./call.mp3');
const call = await t1.transcribe(buffer, { filename: 'call.mp3' });

文字列がhttp://かhttps://で始まればリンク、それ以外ならファイルパスとして扱います。YouTube、X、TikTok、Instagram、Facebook、Bluesky、Twitch、Dailymotion、Pinterest、LinkedIn、Snapchatのリンクに対応しています。追加対応したソースではHTTPSが必要です。文字起こしできる公開動画、字幕の対応状況、利用条件は対応ソースとオプションで確認してください。ファイルもアップロードできます。上限は2,000,000,000バイトで、拡張子はmp3、wav、m4a、flac、ogg、opus、mp4、mov、webm、mkvに対応しています。

SNSのリンクには公開投稿のURLを使ってください。動画が複数ある投稿では、最初の動画だけを文字起こしします。APIがリンクからプラットフォームを判定するため、手動での指定は不要です。短縮リンクの対応状況や制限は対応ソースとオプションを参照してください。

Blob、ReadableStream<Uint8Array>、Uint8Arrayのチャンクを返す非同期イテラブルも使えます。Blobにはfilenameが必要ですが、名前を持つFileなら省略できます。ストリームと非同期イテラブルでは、filenameに加えてバイト単位のsizeも指定してください。

テキストや字幕をダウンロードする

download(id, options)で文字起こしを取得できます。処理中なら完了まで待ち、文字列で返します。JSONを選んだ場合も、パース済みのオブジェクトではなく、APIが返したJSON文字列です。

const text = await t1.download(done.id); // text is the default
const withTimes = await t1.download(done.id, { timestamps: true });
const srt = await t1.download(done.id, { format: 'srt' });
const vtt = await t1.download(done.id, { format: 'vtt' });
const json = await t1.download(done.id, { format: 'json' });

timestamps: trueはtext専用です。ほかの形式に指定すると、invalid_inputでPromiseはrejectされます。対象のジョブが失敗した場合やキャンセルされた場合も、downloadのPromiseはrejectされます。

完了を待たずにジョブを作成する

transcriptions.createなら、文字起こしの完了を待たずにジョブを作成できます。ただし、ファイルを渡した場合は、アップロードを終えてから返ります。

const job = await t1.transcriptions.create('./long-interview.mp4');
const now = await t1.transcriptions.get(job.id);
const finished = await t1.transcriptions.get(job.id, { wait: true });

getは通常、現在の状態をすぐに返します。wait: trueを付けると、completed、failed、canceledのいずれかになるまで待ちます。transcribeと違い、ジョブの失敗やキャンセルを理由にPromiseがrejectされることはありません。本文を読む前に、finished.statusを確認してください。

ジョブの一覧・削除とアカウントの確認

for await (const item of t1.transcriptions.list({ status: 'completed', limit: 50 })) {
  console.log(item.id, item.created_at);
}
 
await t1.transcriptions.delete(job.id);
const account = await t1.account();
console.log(account.minutes.remaining);

listはループの進行に合わせて次のページを取得します。statusやplatformで絞り込めます。platformの値はyoutube、x、tiktok、instagram、facebook、bluesky、twitch、dailymotion、pinterest、linkedin、snapchat、uploadです。limitは1ページの件数で、1〜100を指定できます。APIのデフォルトは20件です。レスポンスのフィールド名は、APIと同じsnake_caseのままです。media_idは内部の形式を解釈せず、受け取った文字列のまま扱ってください。

deleteは、処理中のジョブならキャンセルし、終了済みならジョブと文字起こしを削除します。accountでプラン、残りの分数、利用上限を取得できます。

オプション

インスタンスの作成時に、apiKey、baseUrl、fetch、maxRetriesを指定できます。baseUrlを省略すると、環境変数TRANSCRIPT1_API_URLの値を使います。環境変数もなければhttps://api.transcript1.comに接続します。独自のfetch実装を使うにはfetchで渡してください。maxRetriesは0〜10の整数で、デフォルトは2です。

transcribeとtranscriptions.createでは、次のオプションが共通です。

オプション内容
speakers話者分離を有効にします。
languageデフォルトはautoです。ISO 639-1の言語コードも指定できます。
sourceリンクの処理方法としてautoかsttを指定します。YouTube、X、TikTok、Bluesky、Dailymotion、LinkedInでは、使える字幕があればcaptionsも選べます。
freshリンクの文字起こしを、過去24時間以内の処理済みデータを使わずに作り直します。
filenameBuffer、名前のないBlob、ストリームでは必須です。元のファイル名とは別の名前も指定できます。
sizeバイト単位のサイズです。ストリームと非同期イテラブルでは必須です。
idempotencyKey省略すると、呼び出すたびに新しいUUIDを使います。
onProgress進捗イベントを受け取るコールバックです。
signal呼び出しを中断するためのAbortSignalです。

transcriptions.getにはwait、includeWords、onProgress、signalを指定できます。単語ごとのタイムスタンプを取得するには、includeWords: trueを付けてください。完了待ちの状態変化はonProgressで受け取れます。

downloadのオプションはformat、timestamps、signalです。listにもsignalを指定できます。transcriptions.delete(id, options)やaccount(options)では、オプションに{ signal }を渡します。

進捗を受け取る

onProgressで進捗イベントを受け取れます。transcribe、transcriptions.create、完了待ちのtranscriptions.getで使えます。

await t1.transcribe('./interview.m4a', {
  onProgress(event) {
    console.log(event);
  },
});
イベントフィールド
uploadsentが送信済み、totalが全体のサイズです。どちらもバイト単位です。
statusstatusに現在のジョブの状態が入ります。
waiting_slotジョブの空き枠を待っています。retryAfterは次の試行までの秒数です。
reconnecting追加フィールドはありません。完了待ちの接続が途切れるたびに、1回だけ通知します。

呼び出しを中断する

呼び出しを途中で止めるには、AbortControllerから取得したAbortSignalを渡してください。時間で打ち切る場合はAbortSignal.timeoutを使います。

await t1.transcribe('https://youtu.be/dQw4w9WgXcQ', {
  signal: AbortSignal.timeout(10 * 60_000),
});

最初のリクエストを送る前に中断した場合、Promiseはabortedでrejectされ、ジョブIDはありません。アップロード中に中断した場合は、SDKがawaiting_uploadのジョブの削除を試みます。その後、ジョブIDを含むabortedエラーでPromiseはrejectされます。

完了待ちを中断しても、サーバー上のジョブは止まりません。エラーのtranscriptionIdを使い、transcriptions.get(id, { wait: true })で再び完了を待てます。ジョブそのものをキャンセルするには、transcriptions.delete(id)を呼び出してください。

完了待ちの間は、ネットワークエラーとHTTPの429、500、502、503、504を回数制限なしで再試行します。再接続までの待ち時間は2秒、4秒、8秒、16秒と延び、以降は30秒です。それ以外のリクエストにはmaxRetriesを適用します。ジョブの作成時に同時処理枠が埋まっている場合も、空きを待って再試行します。待ち時間全体を制限したい場合は、signalを指定してください。

エラー

API、ジョブ、SDKのエラーは、Transcript1Errorをキャッチして処理します。

import { Transcript1Error } from '@transcript1/sdk';
 
try {
  await t1.transcribe('./call.mp3');
} catch (error) {
  if (error instanceof Transcript1Error) {
    console.error(error.code, error.message, error.transcriptionId);
  }
}
フィールド内容
messageエラーの説明です。
codeAPIやジョブのエラーコード、canceled、SDK側のエラーコードのいずれかです。
statusHTTPステータスです。ジョブの失敗やSDK内のエラーでは付きません。
detailsminutes_neededやaction_urlなど、APIエラーの補足情報です。デフォルトは空のオブジェクトです。
retryable再試行で成功する可能性があればtrueです。デフォルトはfalseです。
transcriptionId取得できている場合は、ジョブIDが入ります。
transcription取得できている場合は、最後に受け取った文字起こしオブジェクトが入ります。

SDK側のエラーコードは、missing_api_key、invalid_input、aborted、network_error、upload_token_refusedです。JSON以外のエラーレスポンスを受け取った場合は、http_<status>になります。

失敗したジョブにエラーオブジェクトがない場合は、transcription_failedになります。完了済みのジョブを取得したのに本文がない場合、transcribeのPromiseはinternal_errorでrejectされます。APIのエラーコードはエラー、レスポンスの各フィールドはAPIリファレンスを参照してください。

動作環境

Node 20.19以降が必要です。BunやDenoでもnode:互換機能での動作を想定していますが、自動テストはNodeでのみ実行しています。SDKはサーバー側で使ってください。APIキーをブラウザーに渡してはいけません。

最終更新 2026年10月16日