Whisper로 음성인식 구현하기 (SpringBoot, OpenAI)

icebox127·2026년 5월 19일

졸업 프로젝트에서 음성 인식을 통한 면접 답변 기능을 구현하기 위해 Whisper를 사용하였다.

1. OpenAi 키 발급

나는 이미 프로젝트 중에 설정 했는데, 아래 글에 설정 부분대로 openAi 계정을 만들고 키를 발급받으면 된다.
gpt api 사용 예시

2. WhisperService 구현

https://developers.openai.com/api/reference/resources/audio/subresources/transcriptions/methods/create
위의 공식 문서 상 api를 참고하여 구현하였다.
원래 바로 음성 파일을 첨부해도 되지만, 나는 텍스트 변환을 비동기 처리할 거라서 배포된 파일 경로를 토대로 분석하도록 했다.

@Service
@RequiredArgsConstructor
public class WhisperService {
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    private final String OPENAI_API = "https://api.openai.com/v1";

    @Value("${openai.api-key}")
    public String openAiApiKey;

    public String transcribe(String url, Answer answer) {
        try {

            InputStream inputStream = new URL(url).openStream();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            headers.setBearerAuth(openAiApiKey);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

            body.add("model", "whisper-1");

            body.add("file", new MultipartInputStreamFileResource(
                    inputStream,
                    "audio.webm"
            ));

            HttpEntity<MultiValueMap<String, Object>> requestEntity =
                    new HttpEntity<>(body, headers);

            ResponseEntity<AnswerResDto.TranscriptionResponse> response =
                    restTemplate.exchange(
                            OPENAI_API + "/audio/transcriptions",
                            HttpMethod.POST,
                            requestEntity,
                            AnswerResDto.TranscriptionResponse.class
                    );

            if (response.getBody() == null) {
                answer.updateGenerationStatus(GenerationStatus.FAIL);
                throw new RuntimeException("STT 응답이 비어있음");
            }

            return response.getBody().getText();

        } catch (Exception e) {
            answer.updateGenerationStatus(GenerationStatus.FAIL);
            throw new RuntimeException("음성 파일 처리 실패", e);
        }
    }
}

참고

https://eastshine12.tistory.com/59

profile
감자의 공부기록🥔

0개의 댓글