録音が完了している場合や、処理する音声の範囲が決まっている場合は、ファイルの文字起こしを使用します。音声をアップロードすると、最終的な文字起こし結果を受け取れます。また、モデルがファイルを処理している間に、テキストをストリーミングで受け取ることもできます。
まずは gpt-transcribe を使用してください。録音した音声を元の言語で文字起こしする際の推奨モデルです。話者ラベル、単語単位のタイムスタンプ、字幕形式、英語への翻訳が必要な場合にのみ、専用モデルを使用してください。
ファイルサイズの上限は 25 MB です。対応する入力形式は mp3、mp4、mpeg、mpga、m4a、wav、webm です。
gpt-transcribe を指定して、音声ファイルを /v1/audio/transcriptions に送信します。
1
2
3
4
5
6
7
8
9
10
11 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/audio.wav"),
model: "gpt-transcribe",
});
console.log(transcription.text); 1
2
3
4
5
6
7
8
9
10 from openai import OpenAI
client = OpenAI()
audio_file = open ( "audio.wav" , "rb" )
transcription = client.audio.transcriptions.create(
model = "gpt-transcribe" , file = audio_file
)
print (transcription.text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/audio.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: "gpt-transcribe",
})
if err != nil {
panic(err)
}
fmt.Println(transcription.Text)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.nio.file.Path;
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("gpt-transcribe")
.build());
System.out.println(result.asTranscription().text()); 1
2
3
4
5
6
7
8
9
10
11
12
13 using OpenAI.Audio;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-transcribe";
AudioClient client = new(model, key);
await using FileStream audio = File.OpenRead("audio.wav");
AudioTranscription transcription = await client.TranscribeAudioAsync(
audio,
"audio.wav"
);
Console.WriteLine(transcription.Text); 1
2
3
4
5
6
7
8
9
10 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("audio.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-transcribe"
)
puts(transcript.text) 1
2
3
4
5 openai audio:transcriptions create \
--model gpt-transcribe \
--file /path/to/file/audio.mp3 \
--raw-output \
--transform text 1
2
3
4
5
6 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/audio.mp3 \
--form model=gpt-transcribe
モデルは文字起こし結果と検出した言語を JSON で返します。
1 2 3 4 {
"text" : "Bonjour, pouvez-vous m'entendre ?" ,
"languages" : [{ "code" : "fr" }]
}
モデルが十分な信頼度で言語を推定できない場合は、"languages": [] を返します。リクエストとレスポンスの全フィールドについては、音声 API リファレンス を参照してください。
文字起こしへのコンテキストの追加
gpt-transcribe で prompt、keywords、languages を使用すると、専門用語や複数の言語を含む音声の文字起こし精度を向上できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const request = {
model: "gpt-transcribe",
file: fs.createReadStream("fixtures/audio.wav"),
prompt: "A customer support call about a premium plan and account AC-42.",
};
const transcription = await openai.audio.transcriptions.create(request, {
body: {
...request,
keywords: ["premium plan", "AC-42", "billing"],
languages: ["en", "fr"],
},
});
console.log(transcription.text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from openai import OpenAI
client = OpenAI()
with open ( "meeting.wav" , "rb" ) as audio_file:
transcription = client.audio.transcriptions.create(
model = "gpt-transcribe" ,
file = audio_file,
prompt = "A customer support call about a premium plan and account AC-42." ,
extra_body = {
"keywords" : [ "premium plan" , "AC-42" , "billing" ],
"languages" : [ "en" , "fr" ],
},
)
print (transcription.text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/audio.wav")
if err != nil {
panic(err)
}
defer file.Close()
parameters := openai.AudioTranscriptionNewParams{
File: file,
Model: "gpt-transcribe",
Prompt: openai.String("A customer support call about a premium plan and account AC-42."),
}
parameters.SetExtraFields(map[string]any{
"keywords": []string{"premium plan", "AC-42", "billing"},
"languages": []string{"en", "fr"},
})
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), parameters)
if err != nil {
panic(err)
}
fmt.Println(transcription.Text)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.JsonValue;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.nio.file.Path;
import java.util.List;
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("gpt-transcribe")
.prompt("A customer support call about a premium plan and account AC-42.")
.putAdditionalBodyProperty(
"keywords", JsonValue.from(List.of("premium plan", "AC-42", "billing")))
.putAdditionalBodyProperty("languages", JsonValue.from(List.of("en", "fr")))
.build());
System.out.println(result.asTranscription().text()); 1
2
3
4
5
6
7
8
9
10
11 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("audio.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-transcribe",
keywords: ["OpenAI", "Responses API", "Codex"]
)
puts(transcript.text) 1
2
3
4
5
6
7
8
9
10
11 curl https://api.openai.com/v1/audio/transcriptions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F model="gpt-transcribe" \
-F file="@/path/to/file/meeting.wav" \
-F 'prompt=A customer support call about a premium plan and account AC-42.' \
-F 'keywords[]=premium plan' \
-F 'keywords[]=AC-42' \
-F 'keywords[]=billing' \
-F 'languages[]=en' \
-F 'languages[]=fr'
録音に関するコンテキストを自由形式で指定するには、prompt を使用します。
音声に含まれると予想される用語をそのまま指定するには、keywords を使用します。
想定される入力言語を指定するには、languages を使用します。
キーワードはヒントであり、出力を必須にするものではありません。関連する用語だけを含め、発話されていない用語を出力させずに精度が向上するかを評価してください。
gpt-transcribe では、単数形の language フィールドに代わって languages を使用します。両方のフィールドを送信しないでください。各キーワードは 1 行に収め、<、>、キャリッジリターン、ラインフィードを含めないでください。これらの文字が含まれている場合や、prompt がモデルの長さ制限を超えている場合、API はリクエスト全体を拒否します。
録音の各部分で誰が話しているかを識別する必要がある場合にのみ、gpt-4o-transcribe-diarize を使用してください。このモデルは話者ラベルの付与に特化しており、通常のファイルの文字起こしには推奨されません。
レスポンス形式に diarized_json を指定すると、speaker、start、end のメタデータを含むセグメントを受け取れます。30 秒を超える音声では、chunking_strategy を "auto" または音声区間検出の構成に設定してください。
必要に応じて、known_speaker_names[] と known_speaker_references[] で最大 4 つの短い参照音声を指定し、セグメントを既知の話者に対応付けることができます。参照クリップは 2~10 秒の長さにし、メインの音声アップロードで対応している入力形式を使用してください。マルチパートフォームデータを使用する場合は、データ URL としてエンコードしてください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const agentRef = fs.readFileSync("fixtures/agent.wav").toString("base64");
const transcript = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/meeting.wav"),
model: "gpt-4o-transcribe-diarize",
response_format: "diarized_json",
chunking_strategy: "auto",
known_speaker_names: ["agent"],
known_speaker_references: ["data:audio/wav;base64," + agentRef],
});
for (const segment of transcript.segments) {
if (!("speaker" in segment)) continue;
console.log(
`${segment.speaker}: ${segment.text}`,
segment.start,
segment.end
);
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import base64
from openai import OpenAI
client = OpenAI()
def to_data_url (path: str ) -> str :
with open (path, "rb" ) as fh:
return "data:audio/wav;base64," + base64.b64encode(fh.read()).decode( "utf-8" )
with open ( "meeting.wav" , "rb" ) as audio_file:
transcript = client.audio.transcriptions.create(
model = "gpt-4o-transcribe-diarize" ,
file = audio_file,
response_format = "diarized_json" ,
chunking_strategy = "auto" ,
extra_body = {
"known_speaker_names" : [ "agent" ],
"known_speaker_references" : [to_data_url( "agent.wav" )],
},
)
for segment in transcript.segments:
print (segment.speaker, segment.text, segment.start, segment.end) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 package main
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"os"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/shared/constant"
)
type diarizedTranscript struct {
Segments []struct {
Speaker string `json:"speaker"`
Text string `json:"text"`
Start float64 `json:"start"`
End float64 `json:"end"`
} `json:"segments"`
}
func main() {
agentAudio, err := os.ReadFile("fixtures/agent.wav")
if err != nil {
panic(err)
}
meeting, err := os.Open("fixtures/meeting.wav")
if err != nil {
panic(err)
}
defer meeting.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: meeting,
Model: "gpt-4o-transcribe-diarize",
ResponseFormat: openai.AudioResponseFormatDiarizedJSON,
ChunkingStrategy: openai.AudioTranscriptionNewParamsChunkingStrategyUnion{
OfAuto: constant.ValueOf[constant.Auto](),
},
KnownSpeakerNames: []string{"agent"},
KnownSpeakerReferences: []string{"data:audio/wav;base64," + base64.StdEncoding.EncodeToString(agentAudio)},
})
if err != nil {
panic(err)
}
var result diarizedTranscript
if err := json.Unmarshal([]byte(transcription.RawJSON()), &result); err != nil {
panic(err)
}
for _, segment := range result.Segments {
fmt.Println(segment.Speaker+":", segment.Text, segment.Start, segment.End)
}
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 import com.fasterxml.jackson.databind.json.JsonMapper;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.AudioResponseFormat;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import com.openai.models.audio.transcriptions.TranscriptionDiarized;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
Path audio = Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH"));
Path speakerAudio = Path.of(System.getenv("OPENAI_EXAMPLE_SPEAKER_AUDIO_PATH"));
String speakerReference =
"data:audio/wav;base64,"
+ Base64.getEncoder().encodeToString(Files.readAllBytes(speakerAudio));
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(audio)
.model("gpt-4o-transcribe-diarize")
.responseFormat(AudioResponseFormat.DIARIZED_JSON)
.chunkingStrategyAuto()
.addKnownSpeakerName("agent")
.addKnownSpeakerReference(speakerReference)
.build());
TranscriptionDiarized diarized =
result.isDiarized()
? result.asDiarized()
: new JsonMapper()
.readValue(result.asTranscription().text(), TranscriptionDiarized.class);
for (var segment : diarized.segments()) {
System.out.println(
segment.speaker()
+ ": "
+ segment.text()
+ " ("
+ segment.start()
+ "-"
+ segment.end()
+ ")");
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 require "base64"
require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("meeting.wav")
speaker_reference = Base64.strict_encode64(File.binread("agent.wav"))
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-4o-transcribe-diarize",
response_format: :diarized_json,
chunking_strategy: :auto,
known_speaker_names: ["agent"],
known_speaker_references: ["data:audio/wav;base64,#{speaker_reference}"]
)
segments = Array(
transcript.to_h.fetch(:segments) do
raise "The transcription did not include speaker segments"
end
)
segments.each do |segment|
segment = Hash.try_convert(segment) or raise "Invalid speaker segment"
puts(
"#{segment.fetch(:speaker)}: #{segment.fetch(:text)} " \
"(#{segment.fetch(:start)}-#{segment.fetch(:end_)})"
)
end 1
2
3
4
5
6
7
8
9
10 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/meeting.wav \
--form model=gpt-4o-transcribe-diarize \
--form response_format=diarized_json \
--form chunking_strategy=auto \
--form 'known_speaker_names[]=agent' \
--form 'known_speaker_references[]=data:audio/wav;base64,AAA...'
stream=true の場合、話者ラベル付きのレスポンスでは、セグメントが完了するたびに transcript.text.segment イベントが送信されます。transcript.text.delta イベントには segment_id フィールドが含まれますが、差分には部分的な話者の割り当て情報は含まれません。モデルが話者を割り当てるのは、セグメントを確定するときだけです。
話者ラベルの付与は /v1/audio/transcriptions で利用できます。
リアルタイム文字起こしセッションでは対応していません。
録音済みの音声を英語に翻訳するには、/v1/audio/translations で whisper-1 を使用します。録音の元の言語を維持する文字起こしとは異なり、このエンドポイントは英語のテキストを返します。
1
2
3
4
5
6
7
8
9
10
11 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const translation = await openai.audio.translations.create({
file: fs.createReadStream("fixtures/german.wav"),
model: "whisper-1",
});
console.log(translation.text); 1
2
3
4
5
6
7
8
9
10
11 from openai import OpenAI
client = OpenAI()
audio_file = open ( "german.wav" , "rb" )
translation = client.audio.translations.create(
model = "whisper-1" ,
file = audio_file,
)
print (translation.text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/german.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
translation, err := client.Audio.Translations.New(context.Background(), openai.AudioTranslationNewParams{
File: file,
Model: openai.AudioModelWhisper1,
})
if err != nil {
panic(err)
}
fmt.Println(translation.Text)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.translations.TranslationCreateParams;
import java.nio.file.Path;
var result =
client
.audio()
.translations()
.create(
TranslationCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("whisper-1")
.build());
System.out.println(result.asTranslation().text()); 1
2
3
4
5
6
7
8
9
10
11
12 using OpenAI.Audio;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
AudioClient client = new("whisper-1", key);
await using FileStream audio = File.OpenRead("german.wav");
AudioTranslation translation = await client.TranslateAudioAsync(
audio,
"german.wav"
);
Console.WriteLine(translation.Text); 1
2
3
4
5
6
7 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("german.wav")
translation = client.audio.translations.create(file: audio, model: "whisper-1")
puts(translation.text) 1
2
3
4
5
6 curl --request POST \
--url https://api.openai.com/v1/audio/translations \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/german.mp3 \
--form model=whisper-1 \
英語以外の言語で録音された音声の場合、レスポンスには英語への翻訳が含まれます。
Hello, my name is Wolfgang and I come from Germany. Where are you heading today?
このエンドポイントは英語への翻訳にのみ対応しています。
入力される言語があらかじめわかっている場合は、gpt-transcribe で languages を使用してください。対応する言語コードの形式には、次のものがあります。
en、es、fr などの ISO 639-1 コード
eng、spa、yue、cmn など、一部の ISO 639-3 コード
zh-cn、zh-tw、zh-hk など、地域を指定した zh のロケールコード
API は、未対応の言語コードや形式が正しくない言語コードを拒否します。レスポンスには、モデルが十分な信頼度で検出できた言語も含まれます。
whisper-1 については、Whisper の言語一覧 を参照してください。Whisper は 98 言語に対応していますが、精度は言語によって異なります。言語のヒントを 1 つ受け付ける既存のモデルでは、languages の代わりに language を使用します。
単語単位またはセグメント単位のタイムスタンプが必要な場合は、whisper-1 を使用してください。timestamp_granularities[] パラメーター を使用すると、字幕作成や動画編集に利用できる構造化されたタイムスタンプデータが返されます。
1
2
3
4
5
6
7
8
9
10
11
12
13 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/audio.wav"),
model: "whisper-1",
response_format: "verbose_json",
timestamp_granularities: ["word"],
});
console.log(transcription.words); 1
2
3
4
5
6
7
8
9
10
11
12
13 from openai import OpenAI
client = OpenAI()
audio_file = open ( "speech.wav" , "rb" )
transcription = client.audio.transcriptions.create(
file = audio_file,
model = "whisper-1" ,
response_format = "verbose_json" ,
timestamp_granularities = [ "word" ],
)
print (transcription.words) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/audio.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: openai.AudioModelWhisper1,
ResponseFormat: openai.AudioResponseFormatVerboseJSON,
TimestampGranularities: []string{"word"},
})
if err != nil {
panic(err)
}
fmt.Println(transcription.Words)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.AudioResponseFormat;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.nio.file.Path;
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("whisper-1")
.responseFormat(AudioResponseFormat.VERBOSE_JSON)
.addTimestampGranularity(TranscriptionCreateParams.TimestampGranularity.WORD)
.build());
result
.asVerbose()
.words()
.orElseThrow()
.forEach(
word -> System.out.println(word.word() + ": " + word.start() + " - " + word.end())); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 using OpenAI.Audio;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "whisper-1";
AudioClient client = new(model, key);
await using FileStream audio = File.OpenRead("speech.wav");
AudioTranscriptionOptions options = new()
{
ResponseFormat = AudioTranscriptionFormat.Verbose,
TimestampGranularities = AudioTimestampGranularities.Word,
};
AudioTranscription transcription = await client.TranscribeAudioAsync(
audio,
"speech.wav",
options
);
foreach (TranscribedWord word in transcription.Words)
{
Console.WriteLine(
$"{word.Word}: {word.StartTime.TotalSeconds:0.00}s - {word.EndTime.TotalSeconds:0.00}s"
);
} 1
2
3
4
5
6
7
8
9
10
11
12
13 require "openai"
require "pathname"
require "pp"
client = OpenAI::Client.new
audio = Pathname("audio.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "whisper-1",
response_format: :verbose_json,
timestamp_granularities: [:word]
)
pp(transcript[:words]) 1
2
3
4
5
6
7 curl https://api.openai.com/v1/audio/transcriptions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F file="@/path/to/file/audio.mp3" \
-F "timestamp_granularities[]=word" \
-F model="whisper-1" \
-F response_format="verbose_json"
timestamp_granularities[] パラメーターに対応しているのは whisper-1 のみです。
Transcriptions API は最大 25 MB のファイルを受け付けます。それより大きい録音ファイルには、圧縮音声形式を使用するか、ファイルを 25 MB 以下のチャンクに分割してください。文の途中で分割すると、コンテキストが失われて精度が低下する可能性があるため、避けてください。
対処方法の 1 つとして、オープンソースの Python パッケージ PyDub で音声を分割できます。
1
2
3
4
5
6
7
8
9
10 from pydub import AudioSegment
song = AudioSegment.from_wav( "good_morning.wav" )
# PyDub handles time in milliseconds
ten_minutes = 10 * 60 * 1000
first_10_minutes = song[:ten_minutes]
first_10_minutes.export( "good_morning_10.wav" , format = "wav" )
OpenAI は、PyDub などのサードパーティ製ソフトウェアの使いやすさやセキュリティについて、一切保証しません。
プロンプト を使用すると、固有名詞、略語、書式、録音に固有の語彙の認識を改善できます。gpt-transcribe では、文字起こしへのコンテキストの追加 で説明した keywords と languages をプロンプトと組み合わせて使用してください。
既存の gpt-4o-transcribe と gpt-4o-mini-transcribe を使用した連携でも、プロンプトを利用できます。gpt-4o-transcribe-diarize はプロンプトに対応していません。
プロンプトは、次のような場面で役立ちます。
製品名、専門用語、頭字語の正確な文字起こし
長い録音を分割した際の、前のチャンクからのコンテキストの引き継ぎ
句読点、大文字と小文字の区別、フィラーの保持
言語に応じた希望の表記体系の選択
whisper-1 のプロンプトには 224 トークンの制限があり、推奨される文字起こしモデルほど細かく出力を制御できません。ワークフローで Whisper が必要な場合は、信頼性の向上 をご覧ください。
ファイルの文字起こしでは、モデルが録音済みの音声を処理している間に、テキストを逐次ストリーミングできます。リアルタイムセッションは必要ありません。
gpt-transcribe で stream=true を設定します。Transcriptions API は、モデルが録音の各部分を文字起こしするたびに、文字起こしイベント を返します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const stream = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/speech.wav"),
model: "gpt-transcribe",
stream: true,
});
for await (const event of stream) {
console.log(event);
} 1
2
3
4
5
6
7
8
9
10
11
12
13 from openai import OpenAI
client = OpenAI()
audio_file = open ( "speech.wav" , "rb" )
stream = client.audio.transcriptions.create(
model = "gpt-transcribe" ,
file = audio_file,
stream = True ,
)
for event in stream:
print (event) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/speech.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
stream := client.Audio.Transcriptions.NewStreaming(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: "gpt-transcribe",
})
for stream.Next() {
fmt.Println(stream.Current().Type)
}
if err := stream.Err(); err != nil {
panic(err)
}
} 1
2
3
4
5
6
7
8
9
10
11 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("speech.wav")
stream = client.audio.transcriptions.create_streaming(
file: audio,
model: "gpt-transcribe"
)
stream.each { |event| puts(event.type) } 1
2
3
4
5
6
7 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@example.wav \
--form model=gpt-transcribe \
--form stream=true
モデルは音声の文字起こし中に transcript.text.delta イベントを発行し、最後の transcript.text.done イベントで文字起こしの全文を返します。response_format="diarized_json" を指定して話者ラベル付きの文字起こしを行う場合、話者分離モデルはセグメントを確定するたびに transcript.text.segment イベントも発行します。
gpt-transcribe では、最後のイベントに検出された言語も含まれます。
1 2 3 4 5 {
"type" : "transcript.text.done" ,
"text" : "Bonjour, pouvez-vous m'entendre ?" ,
"languages" : [{ "code" : "fr" }]
}
既存の gpt-4o-transcribe、gpt-4o-mini-transcribe、
gpt-4o-transcribe-diarize を使用した連携でも、ファイルのストリーミングをサポートしています。
whisper-1 はサポートしていません。
マイク、通話、メディアストリームからのライブ音声には、上記のファイル向けストリーミングの手順ではなく、リアルタイム文字起こし ガイドを使用してください。このガイドでは、現在の文字起こしセッションのフローと、gpt-live-transcribe を使用する推奨のリアルタイム処理手順を説明しています。
タイムスタンプ、字幕、翻訳のために whisper-1 を使用する場合、以下の手法で珍しい単語や頭字語の認識精度を向上できる可能性があります。汎用的な文字起こしを新たに実装する場合は、これらの手法の代わりに gpt-transcribe から始め、文字起こしのコンテキスト を使用してください。
prompt パラメーターの使用 1 つ目の方法では、省略可能な prompt パラメーターを使って、正しい綴りの辞書を渡します。
Whisper は汎用テキストモデルのように指示に従うわけではなく、受け付けるプロンプトは最大 224 トークンです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream("fixtures/speech.wav"),
model: "whisper-1",
response_format: "text",
prompt:
"ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.",
});
console.log(transcription); 1
2
3
4
5
6
7
8
9
10
11
12
13 from openai import OpenAI
client = OpenAI()
audio_file = open ( "speech.wav" , "rb" )
transcription = client.audio.transcriptions.create(
model = "whisper-1" ,
file = audio_file,
response_format = "text" ,
prompt = "ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T." ,
)
print (transcription.text) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
func main() {
file, err := os.Open("fixtures/speech.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
var transcription []byte
err = client.Post(context.Background(), "audio/transcriptions", openai.AudioTranscriptionNewParams{
File: file,
Model: openai.AudioModelWhisper1,
ResponseFormat: openai.AudioResponseFormatText,
Prompt: openai.String("ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T."),
}, &transcription)
if err != nil {
panic(err)
}
fmt.Println(string(transcription))
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.HttpResponse;
import com.openai.models.audio.AudioResponseFormat;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
try (HttpResponse result =
client
.audio()
.transcriptions()
.withRawResponse()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("whisper-1")
.responseFormat(AudioResponseFormat.TEXT)
.prompt(
"ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, "
+ "OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., "
+ "Q.U.A.R.T.Z., F.L.I.N.T.")
.build())) {
System.out.println(new String(result.body().readAllBytes(), StandardCharsets.UTF_8));
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 using OpenAI.Audio;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "whisper-1";
AudioClient client = new(model, key);
await using FileStream audio = File.OpenRead("speech.wav");
AudioTranscriptionOptions options = new()
{
ResponseFormat = AudioTranscriptionFormat.Text,
Prompt = "ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.",
};
AudioTranscription transcription = await client.TranscribeAudioAsync(
audio,
"speech.wav",
options
);
Console.WriteLine(transcription.Text); 1
2
3
4
5
6
7
8
9
10
11 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("speech.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "whisper-1",
prompt: "The speaker says OpenAI and Responses API"
)
puts(transcript.text) 1
2
3
4
5
6
7 curl --request POST \
--url https://api.openai.com/v1/audio/transcriptions \
--header "Authorization: Bearer $OPENAI_API_KEY" \
--header 'Content-Type: multipart/form-data' \
--form file=@/path/to/file/speech.mp3 \
--form model=whisper-1 \
--form prompt="ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T." この手法は信頼性の向上に役立ちますが、224 トークンの制限があります。そのため、処理規模が拡大しても活用するには、SKU のリストを比較的小さく抑える必要があります。
テキストモデルによる後処理 2 つ目の方法では、テキストモデルを使って文字起こし結果を後処理します。
system_prompt 変数で指示を指定します。文字起こしのプロンプトと同様に、会社名や製品名を含めることができます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 const systemPrompt = `
You are a helpful assistant for the company ZyntriQix. Your task is
to correct any spelling discrepancies in the transcribed text. Make
sure that the names of the following products are spelled correctly:
ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array,
OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K.,
Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary punctuation such as
periods, commas, and capitalization, and use only the context provided.
`;
const transcript = await transcribe(audioFile);
const completion = await openai.chat.completions.create({
model: "gpt-4.1",
temperature: temperature,
messages: [
{
role: "system",
content: systemPrompt,
},
{
role: "user",
content: transcript,
},
],
store: true,
});
console.log(completion.choices[0].message.content); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 system_prompt = """
You are a helpful assistant for the company ZyntriQix. Your task is to correct
any spelling discrepancies in the transcribed text. Make sure that the names of
the following products are spelled correctly: ZyntriQix, Digique Plus,
CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal
Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary
punctuation such as periods, commas, and capitalization, and use only the
context provided.
"""
def generate_corrected_transcript (temperature, system_prompt, audio_file):
response = client.chat.completions.create(
model = "gpt-4.1" ,
temperature = temperature,
messages = [
{ "role" : "system" , "content" : system_prompt},
{ "role" : "user" , "content" : transcribe(audio_file, "" )},
],
)
return response.choices[ 0 ].message.content
corrected_text = generate_corrected_transcript( 0 , system_prompt, fake_company_filepath) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go/v3"
)
const systemPrompt = `
You are a helpful assistant for the company ZyntriQix. Your task is
to correct any spelling discrepancies in the transcribed text. Make
sure that the names of the following products are spelled correctly:
ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array,
OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K.,
Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary punctuation such as
periods, commas, and capitalization, and use only the context provided.
`
func main() {
file, err := os.Open("fixtures/speech.wav")
if err != nil {
panic(err)
}
defer file.Close()
client := openai.NewClient()
transcription, err := client.Audio.Transcriptions.New(context.Background(), openai.AudioTranscriptionNewParams{
File: file,
Model: openai.AudioModelGPT4oTranscribe,
})
if err != nil {
panic(err)
}
completion, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: "gpt-4.1",
Temperature: openai.Float(0),
Messages: []openai.ChatCompletionMessageParamUnion{
openai.SystemMessage(systemPrompt),
openai.UserMessage(transcription.Text),
},
Store: openai.Bool(true),
})
if err != nil {
panic(err)
}
fmt.Println(completion.Choices[0].Message.Content)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.audio.transcriptions.TranscriptionCreateParams;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
import java.nio.file.Path;
String systemPrompt =
"""
You are a helpful assistant for the company ZyntriQix. Your task is to
correct any spelling discrepancies in the transcribed text. Make sure that
the names of the following products are spelled correctly: ZyntriQix,
Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven,
DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.
Only add necessary punctuation such as periods, commas, and capitalization,
and use only the context provided.
""";
var result =
client
.audio()
.transcriptions()
.create(
TranscriptionCreateParams.builder()
.file(Path.of(System.getenv("OPENAI_EXAMPLE_AUDIO_PATH")))
.model("gpt-4o-transcribe")
.build());
var completion =
client
.chat()
.completions()
.create(
ChatCompletionCreateParams.builder()
.model("gpt-4.1")
.temperature(0.0)
.store(true)
.addSystemMessage(systemPrompt)
.addUserMessage(result.asTranscription().text())
.build());
completion.choices().stream()
.flatMap(choice -> choice.message().content().stream())
.forEach(System.out::println); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 using OpenAI.Audio;
using OpenAI.Chat;
string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string model = "gpt-4.1";
ChatClient client = new(model, key);
string transcriptionModel = "gpt-4o-transcribe";
AudioClient audio = new(transcriptionModel, key);
await using FileStream source = File.OpenRead("speech.wav");
AudioTranscription transcription = await audio.TranscribeAudioAsync(source, "speech.wav");
string systemPrompt =
"""
You are a helpful assistant for the company ZyntriQix. Correct any
spelling discrepancies in the transcribed text. Make sure the names
of these products are spelled correctly: ZyntriQix, Digique Plus,
CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven,
DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.
Only add necessary punctuation such as periods, commas, and
capitalization, and use only the context provided.
""";
ChatCompletionOptions correctionOptions = new() { Temperature = 0 };
ChatCompletion completion = await client.CompleteChatAsync(
[
new SystemChatMessage(systemPrompt),
new UserChatMessage(transcription.Text),
],
correctionOptions
);
Console.WriteLine(completion.Content[0].Text); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 require "openai"
require "pathname"
client = OpenAI::Client.new
audio = Pathname("speech.wav")
transcript = client.audio.transcriptions.create(
file: audio,
model: "gpt-4o-mini-transcribe"
)
response = client.responses.create(
model: "gpt-4.1",
input: "Add punctuation and paragraph breaks without changing the words:\n#{transcript.text}"
)
puts(response.output_text) テキストモデルは綴りの誤りを修正でき、Whisper の 224 トークンのプロンプト枠に収まるものより長い用語リストを扱えます。話者の発言内容を変えてしまわないよう、修正内容を元の音声と照合して評価してください。