即時翻譯可讓你將來源音訊串流傳入專用的翻譯工作階段,在說話者仍在發言時,就接收翻譯後的音訊與逐字稿增量。適用於即時口譯、多語言通話、廣播、會議、課程及視訊聊天室。
如果你的應用程式需要翻譯人們說的話,請使用 gpt-realtime-translate。如果你需要能回答問題、呼叫工具及管理對話的助理,則請使用 gpt-realtime-2.1,搭配標準即時工作階段。
翻譯工作階段有何不同
即時翻譯工作階段與語音智慧體工作階段採用不同的架構:
| 語音智慧體工作階段 | 翻譯工作階段 |
|---|---|
連線至 /v1/realtime。 | 連線至 /v1/realtime/translations。 |
| 模型擔任助理。 | 模型擔任口譯員。 |
| 採用對話與回應的生命週期。 | 根據傳入的音訊持續輸出串流。 |
| 可能呼叫工具並產生助理回合。 | 產生翻譯後的音訊與逐字稿增量。 |
你可以呼叫 response.create。 | 你不會呼叫 response.create。 |
翻譯由音訊串流本身觸發。請持續附加音訊,包括語句之間的靜音,並在收到輸出事件時加以處理。
選擇傳輸方式
當瀏覽器負責擷取或播放音訊時,請使用 WebRTC。WebRTC 會以媒體軌傳送來源音訊,並以遠端音軌接收翻譯後的語音,因此你不需要手動重新取樣或播放 PCM 區塊。
如果你的伺服器已接收原始音訊,例如來自 Twilio Media Streams、SIP 媒體、廣播串流輸入或媒體工作程序的音訊,請使用 WebSockets。使用 WebSockets 時,請傳送經 base64 編碼的 24 kHz PCM16 音訊,並自行播放傳回的音訊增量。
建立瀏覽器 WebRTC 工作階段
對於瀏覽器應用程式,請在伺服器上建立短效的用戶端密鑰。請勿在瀏覽器中暴露你的標準 API 金鑰。
app.post("/session", async (req, res) => {
const language = req.body.targetLanguage ?? "es";
const response = await fetch(
"https://api.openai.com/v1/realtime/translations/client_secrets",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
"OpenAI-Safety-Identifier": "hashed-user-id",
},
body: JSON.stringify({
session: {
model: "gpt-realtime-translate",
audio: {
output: { language },
},
},
}),
}
);
res.status(response.status).json(await response.json());
});在瀏覽器中擷取音訊、建立對等連線,並將 SDP 提議以 POST 請求傳送至翻譯通話端點:
const { value: clientSecret } = await fetch("/session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ targetLanguage: "es" }),
}).then((response) => response.json());
const sourceStream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const pc = new RTCPeerConnection();
pc.addTrack(sourceStream.getAudioTracks()[0], sourceStream);
const translatedAudio = new Audio();
translatedAudio.autoplay = true;
pc.ontrack = ({ streams }) => {
translatedAudio.srcObject = streams[0];
};
const events = pc.createDataChannel("oai-events");
events.onmessage = ({ data }) => {
const event = JSON.parse(data);
if (event.type === "session.output_transcript.delta") {
subtitles.textContent += event.delta;
}
};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const sdpResponse = await fetch(
"https://api.openai.com/v1/realtime/translations/calls",
{
method: "POST",
headers: {
Authorization: `Bearer ${clientSecret}`,
"Content-Type": "application/sdp",
},
body: offer.sdp,
}
);
if (!sdpResponse.ok) {
throw new Error(await sdpResponse.text());
}
await pc.setRemoteDescription({
type: "answer",
sdp: await sdpResponse.text(),
});建立 WebSocket 工作階段
連線至專用的翻譯端點,並在 URL 中選擇模型:
執行此範例前,請先為 Node.js 安裝 ws、為 Python 安裝 websocket-client,或為 Ruby 安裝 async-websocket(gem install async-websocket)。
import WebSocket from "ws";
const ws = new WebSocket(
"wss://api.openai.com/v1/realtime/translations?model=gpt-realtime-translate",
{
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
"OpenAI-Safety-Identifier": "hashed-user-id",
},
}
);若使用 Ruby,請將下列用於設定組態與附加音訊的程式碼片段插入 Async::WebSocket::Client.connect 區塊內,放在檢查工作階段是否已建立之後、區塊結束之前。傳送音訊及接收翻譯事件時,請保持連線開啟。
通訊端開啟後,設定目標語言:
ws.on("open", () => {
ws.send(
JSON.stringify({
type: "session.update",
session: {
audio: {
output: {
language: "es",
},
},
},
})
);
});接著持續附加音訊:
ws.send(
JSON.stringify({
type: "session.input_audio_buffer.append",
audio: base64Pcm16,
})
);監聽翻譯後的音訊與逐字稿:
ws.on("message", (data) => {
const event = JSON.parse(data.toString());
if (event.type === "session.output_audio.delta") {
playPcm16(event.delta);
}
if (event.type === "session.output_transcript.delta") {
process.stdout.write(event.delta);
}
if (event.type === "session.input_transcript.delta") {
updateSourceTranscript(event.delta);
}
});關閉 WebSocket 工作階段
來源串流結束時,請先傳送 session.close 事件,再關閉 WebSocket。此事件會指示服務處理完待處理的輸入音訊、輸出所有剩餘的翻譯音訊與逐字稿,然後傳送 session.closed 事件。只有翻譯工作階段支援 session.close 事件。
傳送 session.close 後,請停止附加音訊,並在正常的接收迴圈中繼續讀取事件,直到收到 session.closed。若立即關閉通訊端,可能會遺失工作階段仍在傳出的翻譯結果。
let translationSessionClosing = false;
function closeTranslationSession() {
if (translationSessionClosing) {
return;
}
translationSessionClosing = true;
ws.send(
JSON.stringify({
type: "session.close",
})
);
}
ws.on("message", (data) => {
const event = JSON.parse(data.toString());
if (event.type === "session.output_audio.delta") {
playPcm16(event.delta);
}
if (event.type === "session.output_transcript.delta") {
process.stdout.write(event.delta);
}
if (event.type === "session.input_transcript.delta") {
updateSourceTranscript(event.delta);
}
if (event.type === "session.closed") {
ws.close();
}
});
// Call this when the source stream ends.
closeTranslationSession();建立隨聽翻譯功能
當你需要將單一說話者或串流的音訊翻譯給聽眾收聽時,請使用隨聽翻譯。適用情境包括直播、研討會演講、網路研討會、財報電話會議、講座及影片。
典型架構如下:
source audio -> translation session -> translated audio + subtitles
為每種目標語言建立一個翻譯工作階段。如果同一個英語來源需要西班牙語和法語輸出,請分別建立一個英語轉西班牙語工作階段,以及一個英語轉法語工作階段。
對於瀏覽器隨聽翻譯應用程式,請使用 getDisplayMedia() 擷取分頁音訊,透過 WebRTC 傳送音訊,並播放遠端的翻譯音軌。對於正式環境中的廣播,請在伺服器端的媒體工作程序中執行翻譯,並向聽眾發布翻譯音軌或字幕。
建立對話翻譯功能
當兩位或更多參與者使用不同語言交談時,請使用對話翻譯。適用情境包括客服通話、業務通話、個別教學及視訊聊天室。
請將各參與者的音軌分開。將多位說話者混入同一個串流,會使說話者身分、個別說話者的字幕及重疊語音更難處理。
雙人通話時,請為每個翻譯方向各建立一個翻譯工作階段:
Caller A audio -> translate into Caller B language -> play to Caller B
Caller B audio -> translate into Caller A language -> play to Caller A
群組通話室所需的工作階段數量取決於目前發言的人數和目標語言:
translation sessions ~= active source speaker tracks x distinct target languages
在小型通話室中,每位聽眾都可以在瀏覽器端,為需要翻譯的遠端發言者建立翻譯輔助元件。在較大的通話室中,請使用伺服器端參與者或媒體工作程序,對每位來源發言者只訂閱一次,為每種目標語言建立一個翻譯工作階段,並重新發布翻譯後的音軌。
測試品質與延遲
使用真實音訊測試翻譯,並由熟悉兩種語言的人員進行審查。自動化指標有助於評估,但無法找出使用者會注意到的所有錯誤。
測試項目:
- 語言配對的翻譯品質;
- 名稱、數字、日期、貨幣和電話號碼;
- 特定領域的術語;
- 語碼轉換與混合語言對話;
- 口音、快速說話和多人同時說話;
- 首段翻譯音訊的延遲;
- 語句結束時的延遲;
- 字幕顯示時機;
- 聲音一致性;
- 重新連線行為。
如果您的使用情境需要準確翻譯名稱或領域術語,請在上線前建立一組標準測試資料,並以人工方式審查失敗案例。
正式環境檢查清單
- 瀏覽器媒體請選用 WebRTC,伺服器媒體則選用 WebSockets。
- 使用專用的
/v1/realtime/translations端點。 - 持續串流傳送音訊,包括語句之間的靜音。
- 關閉 WebSocket 工作階段前,請先使用
session.close並等待session.closed。 - 進行對話翻譯時,請將各發言者的音軌分開。
- 每種輸出語言各使用一個工作階段。
- 視需要同時顯示來源語言與目標語言的轉錄文字。
- 提供原始音訊、翻譯音訊、字幕、靜音和音量的控制項。
- 顯示重新連線中、延遲和無法使用等狀態。
- 分別追蹤延遲和翻譯品質。
相關指南
比較語音智慧體、翻譯和轉錄工作階段。
將瀏覽器媒體連接至即時工作階段。
透過伺服器端媒體處理流程串流傳送原始音訊。
以串流方式傳送即時音訊的轉錄文字增量。