티스토리 뷰

AI

OpenAI API 연동 - STEP5) 음성인식

열코 2026. 5. 12. 17:19
반응형

2026.05.08 - [AI] - OpenAI API 연동 - STEP4) 이미지 생성

 

STEP 5에서는 OpenAI의 강력한 음성 인식 모델인 Whisper API를 연동하는 방법을 알아보겠습니다.

이 API는 오디오 파일(mp3, wav, m4a 등)을 업로드하면 이를 매우 높은 정확도의 텍스트로 변환(STT, Speech-to-Text)해 줍니다. 텍스트, 이미지에 이어 '청각' 기능을 추가하는 단계입니다.


STEP 5: Whisper API를 이용한 음성 인식(STT) 연동

1. 음성 인식 처리 흐름

  1. 파일 준비: 녹음된 오디오 파일을 준비합니다.
  2. Multipart 요청: 일반적인 JSON 요청과 달리, 파일 전송을 위해 Multipart/form-data 형식을 사용해야 합니다.
  3. 텍스트 반환: AI가 분석한 대사 내용을 문자열로 반환합니다.

2. STEP 5 실전 예제 코드

Java 11 내장 HttpClient는 Multipart 처리가 다소 복잡하기 때문에, 여기서는 이해를 돕기 위해 파일 데이터와 필수 파라미터를 전송하는 구조를 명확히 보여드립니다.

Java
 
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

public class OpenAI_Step5_Whisper {
    private static final String API_KEY = System.getenv("OPENAI_KEY");
    private static final String WHISPER_API_URL = "https://api.openai.com/v1/audio/transcriptions";

    public static void main(String[] args) {
        // 전송할 음성 파일 경로 (미리 준비되어 있어야 함)
        Path filePath = Paths.get("my_voice_record.mp3");

        try {
            System.out.println("🎙️ 음성 파일을 분석 중입니다...");
            String transcript = transcribeAudio(filePath);
            
            System.out.println("\n✅ 인식된 내용:");
            System.out.println(transcript);
        } catch (Exception e) {
            System.err.println("오류 발생: " + e.getMessage());
        }
    }

    public static String transcribeAudio(Path filePath) throws Exception {
        String boundary = "---" + System.currentTimeMillis();
        
        // Multipart Body 생성 (OpenAI Whisper는 'file'과 'model' 파라미터가 필수)
        byte[] multipartBody = createMultipartBody(boundary, filePath, "whisper-1");

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(WHISPER_API_URL))
                .header("Content-Type", "multipart/form-data; boundary=" + boundary)
                .header("Authorization", "Bearer " + API_KEY)
                .POST(HttpRequest.BodyPublishers.ofByteArray(multipartBody))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() != 200) {
            throw new RuntimeException("음성 인식 실패: " + response.body());
        }

        // 응답에서 텍스트 추출 ({"text": "인식된 내용..."})
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(response.body());
        return rootNode.path("text").asText();
    }

    // 파일 전송을 위한 Multipart 바디 구성 (간략화된 예시)
    private static byte[] createMultipartBody(String boundary, Path path, String modelName) throws IOException {
        String fileName = path.getFileName().toString();
        StringBuilder sb = new StringBuilder();
        
        // 1. 모델 파라미터 추가
        sb.append("--").append(boundary).append("\r\n");
        sb.append("Content-Disposition: form-data; name=\"model\"\r\n\r\n");
        sb.append(modelName).append("\r\n");

        // 2. 파일 헤더 추가
        sb.append("--").append(boundary).append("\r\n");
        sb.append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(fileName).append("\"\r\n");
        sb.append("Content-Type: application/octet-stream\r\n\r\n");

        byte[] header = sb.toString().getBytes();
        byte[] fileBytes = java.nio.file.Files.readAllBytes(path);
        byte[] footer = ("\r\n--" + boundary + "--\r\n").getBytes();

        byte[] combined = new byte[header.length + fileBytes.length + footer.length];
        System.arraycopy(header, 0, combined, 0, header.length);
        System.arraycopy(fileBytes, 0, combined, header.length, fileBytes.length);
        System.arraycopy(footer, 0, combined, header.length + fileBytes.length, footer.length);
        
        return combined;
    }
}

3. 주요 구현 포인트

  • 모델명 (whisper-1): 현재 상용화된 가장 최신 모델입니다.
  • Multipart/form-data: 파일 데이터를 HTTP 프로토콜로 보낼 때 사용하는 규격입니다. 파일 내용뿐만 아니라 파일명, 파일 타입 정보를 함께 보냅니다.
  • 지원 형식: mp3, mp4, mpeg, mpga, m4a, wav, webm 형식을 지원하며, 파일 크기는 최대 25MB로 제한됩니다.

4. 실무 팁

  1. 다국어 지원: Whisper는 한국어를 포함해 수십 개의 언어를 자동으로 감지합니다. 만약 특정 언어로 고정하고 싶다면 language 파라미터(예: "ko")를 추가하면 속도와 정확도가 소폭 향상됩니다.
  2. 프롬프트 활용: prompt 파라미터를 사용해 "이 음성에는 기술적인 용어가 많이 포함되어 있습니다"라고 힌트를 주면 오타(고유명사 등)를 줄일 수 있습니다.

 

2026.05.08 - [AI] - OpenAI API 연동 - STEP6) 비용최적화

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/06   »
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
글 보관함
반응형