
Colab에서 테스트하는 Zoom AI Services - 공개 음성을 텍스트로 변환하고, 반상회 텍스트를 요약·번역하여 Drive에 저장하기
요약
Google Colab 환경에서 Zoom AI Services의 Scribe, Summarizer, Translator API를 활용하여 음성을 텍스트로 변환하고 요약 및 번역하는 과정을 다룹니다. API 인증을 위한 JWT 생성 방법과 보안을 위한 Colab Secrets 활용법을 포함한 실무적인 검증 절차를 안내합니다.
핵심 포인트
- Zoom Scribe, Summarizer, Translator API를 활용한 워크플로우 구현
- JWT(HS256)를 이용한 Zoom AI Services 인증 및 호출 방법
- Colab Secrets를 사용한 API Key 및 Secret의 안전한 관리
- 음성 변환 후 요약 및 번역 결과의 구글 드라이브 저장 프로세스
반상회나 자치회 회의에서는 방재 훈련, 청소 활동, 지역 이벤트, 회계 보고, 어린이 돌봄, 다문화 공생 등 다양한 주제를 다룹니다.
해외 출신 주민이나 일본어를 읽는 것에 익숙하지 않은 참가자가 있는 경우에는, "회의에서 무엇이 결정되었는지"를 일본어뿐만 아니라 다른 언어로도 공유할 수 있으면 편리합니다.
이 기사에서는 Google Colab에서 Zoom AI Services의 다음 API를 호출합니다.
Scribe API: 음성을 텍스트로 변환(Transcription)한다 -
Summarizer API: 변환된 텍스트를 요약(Summarization)한다 -
Translator API: 요약을 영어로 번역(Translation)한다 -
단, 검증 내용은 다음 2단계로 나누어 진행합니다.
- Zoom 공식 문서에서도 사용되는 공개 WAV 파일로 Scribe API의 인증과 통신을 확인한다
- 반상회의 가상적인 변환 완료 텍스트를 사용하여 Summarizer API, Translator API, Google Drive 저장까지 확인한다
즉, 동일한 반상회 음성을 기점으로 3개의 API를 일괄적으로 실행한 사례는 아닙니다. Scribe API의 통신 확인과 그 이후의 요약·번역 처리를 분리함으로써 에러 발생 지점을 구분하기 쉽게 했습니다.
본 기사는 2026년 6월 28일 시점의 검증 메모입니다. API 사양, 이용 조건, 요금, 인증 방식은 변경될 가능성이 있습니다. 실제로 이용할 때는 Zoom의 공식 문서를 확인해 주세요.
또한, 반상회·자치회 시나리오는 가상의 유스케이스(Use case)입니다. 필자가 실제 반상회에서 운용한 사례가 아닙니다.
AI가 생성한 텍스트 변환, 요약, 번역은 그대로 공식 의사록이나 안내문으로 배포하지 않고, 사람이 확인하여 보정한다는 전제로 다룹니다. 특히 일시, 장소, 금액, 담당자, 피난 장소, 긴급 연락처 등의 중요 정보는 반드시 원본 음성이나 관계자의 확인 결과와 대조합니다.
전체 흐름은 다음과 같습니다.
Zoom AI Services의 API 호출에는 Zoom Build Platform에서 발행된 API Key와 API Secret을 사용하여 JWT를 생성합니다.
여기서 사용하는 인증 정보는 일반적인 Zoom OAuth 앱의 Client ID / Client Secret과는 별개의 것입니다. 이용 가능한 기능이나 과금 조건은 Zoom 계정의 계약 상태에 따라 다르므로, 사전에 Zoom Build Platform 측에서 AI Services를 이용할 수 있는 상태로 만들어 둡니다.
Colab에서는 처음에 필요한 라이브러리를 설치합니다.
!pip -q install PyJWT
requests는 일반적인 Colab 환경에 포함되어 있지만, 환경에 따라 부족한 경우에는 함께 설치합니다.
!pip -q install PyJWT requests
Colab 좌측의 열쇠 아이콘을 통해 다음 2개를 Secrets에 등록합니다.
ZOOM_API_KEY
ZOOM_API_SECRET
Notebook에서는 google.colab.userdata로 읽어옵니다.
from google.colab import userdata
ZOOM_API_KEY = userdata.get("ZOOM_API_KEY")
ZOOM_API_SECRET = userdata.get("ZOOM_API_SECRET")
...
API Key나 API Secret을 Notebook 본문에 직접 작성하면 공유 시 인증 정보가 유출될 가능성이 있습니다. Colab Secrets나 환경 변수로 관리하는 것이 더 안전합니다.
Zoom AI Services에서는 API Key / API Secret으로부터 JWT를 생성하여 Bearer token으로서 요청 헤더(Request header)에 설정합니다.
JWT의 서명 알고리즘에는 HS256을 사용하며, 페이로드(Payload)에 iss, iat, exp를 설정합니다.
import time
import jwt
def create_zoom_ai_token(api_key: str, api_secret: str) -> str:
...
이 기사에서는 유효 기간을 1시간으로 설정했습니다. Notebook을 장시간 열어둔 경우에는 기간 만료 후 JWT를 재생성합니다.
Scribe, Summarizer, Translator에서 공통으로 사용하는 POST 처리를 만듭니다.
import json
import requests
ZOOM_BASE_URL = "https://api.zoom.us/v2"
...
처음에는 짧은 공개 WAV 파일로 통신 확인을 진행합니다.
Scribe API Fast mode는 하나의 오디오 파일을 동기적 (Synchronous)으로 처리하는 방식입니다. 짧은 녹음 파일을 확인하는 데 적합합니다.
def transcribe_audio(audio_url: str, language: str) -> dict:
payload = {
"file": audio_url,
...
응답(Response)에서 표시용 전사(Transcription) 본문을 가져옵니다.
def extract_transcript_text(data: dict) -> str:
result = data.get("result")
if isinstance(result, dict):
...
여기까지 동작한다면 다음 항목들을 확인할 수 있습니다.
- Zoom AI Services용 JWT를 생성할 수 있음
- Bearer token으로 인증할 수 있음
- Scribe API에 오디오 URL을 전달할 수 있음
result.text_display로부터 전사 결과를 가져올 수 있음
Scribe API Fast mode에서는 file에 Zoom 측에서 가져올 수 있는 오디오 파일의 URL을 전달합니다.
Colab에서 Google Drive를 마운트하더라도, 다음과 같은 Colab 내부의 경로를 Zoom 서버에서 직접 읽을 수는 없습니다.
/content/drive/MyDrive/chonaikai-sample.wav
또한, Google Drive의 공유 URL을 다운로드 URL로 변환하여 전달했을 때, 이번 검증에서는 다음과 같은 에러가 반환되었습니다.
{
"code": 400,
"reason": "UNSUPPORTED_MEDIA",
...
https://drive.google.com/uc?export=download&id=...와 같은 URL은, URL 상에 파일 확장자가 없을 뿐만 아니라 Google Drive 측의 리다이렉트(Redirect)나 응답 형식 등의 영향으로 인해 Scribe API가 오디오 파일로 판정하지 못했을 가능성이 있습니다.
이 동작은 이번 검증 결과에 기반한 것이며, "모든 Google Drive URL에서 반드시 실패한다"는 의미는 아닙니다.
다만, Scribe API의 입력값으로서 안정적으로 유지하려면 다음과 같은 URL을 준비하는 것이 다루기 쉽습니다.
실제 반상회 음성에는 성명이나 연락처 등의 개인정보가 포함될 가능성이 있습니다. 실제 운영 시에는 완전한 공개 URL을 피하고, 액세스(Access) 만료 시간을 짧게 설정한 서명된 URL (Signed URL)을 사용하는 구성이 안전합니다.
이 기사에서는 Google Drive를 입력 음성의 배포처가 아닌, 처리 결과의 저장소로 사용합니다.
수중에 검증용 회의 음성이 없는 경우에는 Windows PowerShell의 System.Speech를 사용하여 WAV 파일을 생성할 수 있습니다.
Add-Type -AssemblyName System.Speech
$out = Join-Path (Get-Location) "chonaikai-sample.wav"
$synth = New-Object System.Speech.Synthesis.SpeechSynthesizer
...
생성한 chonaikai-sample.wav를 Scribe API에 전달하려면 Zoom 측에서 가져올 수 있는 HTTPS URL을 준비해야 합니다.
이번에는 Scribe API를 통한 일본어 음성 처리를 필수 조건으로 두지 않고, 다음의 전사된 텍스트를 사용하여 Summarizer API 이후의 흐름을 확인합니다.
반상회의 가상 회의를 전사한 것으로 가정하여 다음 텍스트를 사용합니다.
transcript = """
본일 반상회에서는 방재 훈련, 청소 활동, 다문화 공생 안내에 대해 논의했습니다.
먼저, 방재 훈련은 다음 달 둘째 주 토요일 오전 9시부터 제1공원에 모여 실시합니다.
...
실제로 자신의 일본어 음성을 Scribe API로 처리할 수 있는 경우에는, 수기로 작성한 transcript 대신 해당 일본어 음성의 응답에서 가져온 문자열을 사용할 수 있습니다.
# 공개 영어 WAV의 scribe_response가 아니라,
# 자신의 일본어 음성을 처리한 응답을 지정한다
own_scribe_response = transcribe_audio(
...
공개 WAV의 통신 확인을 위해 생성한 scribe_response를 여기서 사용하면, 반상회 텍스트가 아니라 공개 WAV의 영어 전사(Transcription) 결과가 요약 대상이 됩니다. 셀 실행 순서에 따른 덮어쓰기를 방지하기 위해 변수명을 나누어 처리합니다.
회의 카테고리에 따라 확인하고자 하는 내용은 달라집니다.
def category_context(category: str) -> str:
contexts = {
"disaster_prevention": (
...
여기서 수행하고 있는 것은 Summarizer API의 전용 프롬프트(Prompt) 기능을 사용하는 것이 아닙니다. 회의 카테고리에 대한 설명을 입력 텍스트의 맨 앞에 추가하는 실험적인 시도입니다.
카테고리 정보가 항상 기대한 대로 반영된다는 보장은 없으므로, 정식 회의록을 작성할 때는 출력 결과를 확인해야 합니다.
Summarizer API Fast mode로 전사된 텍스트를 전달합니다.
task에 full_summary를 지정하면 Recap, Summary, Action Items를 포함한 요약을 얻을 수 있습니다. 이번 실제 응답에서는 본문이 result.full_summary에 저장되었습니다.
2026년 6월 시점 기준으로, Zoom 공식 Fast mode 설명 페이지에서는 요약 본문을 result.text로, API 레퍼런스(API Reference)에서는 result.full_summary 등 태스크별 필드로 기재하고 있어 공식 문서 내에서도 차이가 있습니다. 이번 실제 응답은 API 레퍼런스 측의 형식이었습니다. 따라서 본 기사에서는 두 가지 형식을 모두 고려하여 추출합니다.
def build_summary_input(transcript: str, category: str) -> str:
context = category_context(category)
return f"{context}\n\n--- transcript ---\n{transcript}"
...
요약을 실행합니다.
MEETING_CATEGORY = "multicultural"
SUMMARY_LANGUAGE = "ja-JP"
summary_response = summarize_meeting(
...
이번에 확인한 task="full_summary" 응답에서는 요약 본문이 result.full_summary에 저장되었습니다. 추출 함수에서는 이 키를 최우선으로 확인하며, 응답 차이에 대비하여 다른 후보 키들도 순차적으로 확인합니다.
Summarizer API Fast mode의 입력 상한은 96 KB입니다.
장시간 회의의 전사 내용을 다룰 경우에는 입력 크기를 확인하고, 필요에 따라 내용을 적절한 단위로 분할하거나 Batch mode를 검토해야 합니다.
Translator API Fast mode는 1회 요청당 하나의 번역 대상 언어를 지정합니다. 또한, 입력 텍스트의 상한은 4,000자입니다.
끝부분을 인지하지 못한 채 잘라버리면 Action Items와 같은 중요 정보가 누락될 가능성이 있습니다. 따라서 이 기사에서는 상한을 초과할 경우 에러로 처리합니다.
TRANSLATOR_MAX_CHARS = 4000
def translate_text(
text: str,
...
일본어 요약을 영어로 번역합니다.
현재 Translator API는 영어와의 상호 번역을 지원하며, 번역 원문 또는 번역 대상 중 하나를 en-US로 설정해야 합니다. 이번 ja-JP에서 en-US로의 번역은 지원 범위 내에 있습니다.
TRANSLATE_TO = "en-US"
translation_response = translate_text(
text=meeting_note_ja,
...
요약이 4,000자를 초과하는 경우에는 단락 단위로 분할하여 여러 번 번역하거나, 요약 내용을 짧게 만들어야 합니다.
마지막으로 전사, 요약, 번역 결과를 Google Drive에 저장합니다.
Markdown은 사람이 읽기 쉬운 형식으로, JSON은 후속 프로그램에서 재사용하기 쉬운 형식으로 저장합니다.
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo
...
저장되는 파일은 다음 4가지입니다.
transcript.md
meeting_note_ja.md
meeting_note_en.md
...
다문화 공생 회의에서는 다음과 같은 일본어 공유 노트를 작성한다고 가정합니다.
# Meeting Note JA
Recap:
町内会では、防災訓練、清掃活動、外国籍住民向け案内の準備について確認した。
...
Translator API로 영어로 변환한 공유 노트는 해외 출신 주민이나 일본어를 읽는 데 익숙하지 않은 참가자를 위한 안내 초안으로 활용할 수 있습니다.
실제 출력 내용은 입력 텍스트나 API 측의 모델에 따라 달라집니다.
요약이나 번역에서는 일시, 고유명사, 담당자, 수치 등을 틀릴 가능성이 있습니다. 중요한 정보는 원본 음성, 원본 자료, 관계자의 확인 결과와 대조해야 합니다.
회의를 녹음하여 외부 AI 서비스로 전송할 경우에는 참가자에 대한 설명, 동의, 보관 기간, 열람 권한 등을 사전에 정리합니다.
실제 회의 음성을 인터넷상에 무기한으로 공개하는 것은 피해야 합니다. 가능하다면 유효 기간을 짧게 설정한 서명된 URL (Signed URL)을 사용합니다.
이 기사에서는 확인 용이성을 우선하여 Fast mode를 사용하고 있습니다. 장시간 음성, 대량 파일, 비동기 처리 (Asynchronous processing)가 필요한 경우에는 각 API의 Batch mode도 검토합니다.
Google Colab에서 Zoom AI Services를 호출하여 다음 흐름을 확인했습니다.
- Colab Secrets에서 Zoom Build Platform의 API Key / API Secret을 가져오기
- PyJWT로 Zoom AI Services용 JWT 생성하기
- 공개 WAV 파일로 Scribe API의 인증 및 통신 확인하기
- 마을 회의(町内会)의 전사(Transcription)된 텍스트를 Summarizer API로 요약하기
- Translator API로 일본어 요약을 영어로 번역하기
- Markdown과 JSON을 Google Drive에 저장하기
이번에는 Scribe API의 통신 확인과 마을 회의 시나리오의 후속 처리를 분리했습니다. 이 구성이라면 음성 취득 문제와 요약·번역 문제를 분리하여 확인할 수 있습니다.
마을 회의처럼 참가자의 IT 기술이나 언어적 배경이 다른 상황에서는 녹음을 남기는 것뿐만 아니라, 내용을 읽기 쉬운 공유 노트로 변환하는 것에 의미가 있습니다.
단, AI가 작성하는 공유 노트는 최종 결과물이 아니라 초안입니다. 사람이 확인하고, 오류를 수정하며, 필요한 보충 설명을 더한 후에 배포합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기