여러분들은 예상치 못한 먼 타지의 영상에서 의외의 아이디어를 얻어본 적, 있으신가요?

인프런은 언어의 장벽을 넘어 폭 넓은 지식을 전달해드리기 위해
자막, 더빙에 이어 영상 화면에 있는 글자까지 번역하는 영상 화면 번역 기능을 준비하고 있습니다.

최근에 인프런에서 공개한 DeNA × AI Day 2026를 포함해, 앞으로도 인프런에서 각국의 컨퍼런스 영상과 강의들을 보실 수 있을 텐데요. 이미 몇 강의에는 화면 번역 기능이 적용되어 있고 새로 추가되는 일부 강의에도 실험적으로 적용될 예정입니다.

그러하여 이번 글에서는 이 기능을 구현하며 고민한 과정을 공유드리려 합니다.

결과 예시

인프런 플레이어 원본 영상 화면
적용 전
인프런 플레이어 화면 번역 결과
적용 후
원본: DeNA × AI Day 2026, 'AI × 업무개혁: AI Workspace 프로젝트의 에이전트 활용 최전선'

번역된 영상을 보여주는 방법

영상 화면 속 글자를 번역하는 기능을 어떻게 구현할 수 있을까요?
우선 번역할 대상 영상이 있어야 하고, 그 화면에 보이는 원문을 번역된 글자로 바꿔야 할 것입니다.

저희는 영상의 글자를 번역본으로 바꿔 보여주기 위해
미리 준비한 번역을 재생 중인 화면 위에 겹쳐 그리는 오버레이 방식을 선택했습니다.

원본 영상은 기존 방식 그대로 재생하면서 글자 뒤쪽 영역만 주변 배경과 같은 색의 박스로 덮어 원문을 가리고, 그 위에 번역된 글자를 같은 자리에 얹는 것입니다.

화면 번역 오버레이 구조
원본 영상 위에 배경색 박스와 번역 텍스트, 두 레이어를 겹쳐 그립니다.

이 방식이라면 영상 인코딩과 상관없이 새로운 언어를 쉽게 추가할 수 있고, 오역을 발견하거나 번역 파이프라인을 개선했을 때도 데이터만 수정하면 바로 반영되니 적은 비용으로 품질을 유연하게 다듬어 갈 수 있습니다.

번역된 텍스트 데이터만 별도로 응답하기에 서버, 클라이언트 모두 네트워크 전송 용량 부담이 적다는 점 또한 큰 이점이었습니다.

구글 렌즈에서도 원문 글자가 배경색으로 가려지고 그 자리에 번역된 글자를 덮어 보여줍니다. 인프런의 화면 번역도 이와 같은 원리입니다. 다만 비추는 즉시 답해야 하는 렌즈와 달리 영상을 미리 분석해 두기 때문에 처리 시간의 제약이 적고, 품질을 더 최적화하거나 잘못된 부분을 사전에 보정할 수 있다는 차이점이 있습니다.

구글 렌즈 이미지 번역 예시
출처: https://blog.google

내부적인 산출물은 JSON 형식의 데이터입니다.

{
  "events": [
    {
      "start": 12.0,
      "end": 47.0,
      "texts": [
        {
          "text": "Part 2. From RNN to Transformer",
          "translations": { "ko": "제2부 RNN에서 Transformer까지" },
          "bbox": [104, 216, 632, 258],
          "bg_color": [16, 42, 67],
          "text_color": [236, 240, 244]
        }
      ]
    }
  ]
}

events는 화면 구성이 유지되는 시간 구간이고, 각 텍스트는 위치(bbox), 원문, 언어별 번역, 그리고 배경색과 글자색을 가집니다. 텍스트를 하나의 평평한 배열로 두는 방법도 있지만 시간 구간(event)으로 묶은 것은 플레이어의 탐색 최적화를 위함입니다. 영상의 특성상, 화면이 전환될 때 모든 텍스트가 한 번에 바뀌는 경우가 잦기 때문입니다.

플레이어는 재생 시각에 해당하는 이벤트를 찾아서, 영상 위에 bbox 위치대로 bg_color로 채운 박스를 깔고 그 위에 text_color로 번역 텍스트를 그립니다. 원문 글자는 배경색 박스에 가려지고, 같은 자리에 번역이 나타나는 구조입니다.

여기까지가 번역된 영상을 보여주는 방법이었습니다. 이제 남은 문제는 이 JSON 데이터를 어떻게 만들어내느냐입니다.

텍스트 추출

영상은 결국 정지된 화면, 즉 프레임의 연속이므로, 먼저 화면 한 장을 번역하는 것부터 생각해 보겠습니다. 초기 구상은 단순하게 떠올릴 수 있습니다.

  1. 화면 속 텍스트를 OCR(광학 문자 인식)로 읽는다.
  2. 읽은 텍스트를 번역한다.
  3. 번역 결과를 원래 텍스트와 같은 위치에 오버레이한다.

세 단계만으로도 화면 번역 자체는 동작합니다.
하지만 실제로 테스트해 보니, 자연스러운 결과물을 만들려면 두 가지 처리가 더 필요했습니다.

가. 번역이 불필요한 텍스트는 제외한다

PPT나 문서 같은 일반적인 번역 대상과 달리, 강의 영상 도메인에는 특유의 어려움이 있습니다. 화면에 자잘한 UI 텍스트나 코드가 함께 나온다는 점입니다.

아주 작은 버튼이나 코드, 명령어, 파일 경로까지 모두 번역하면 시각적 자연스러움을 해치기 쉽습니다. 화면 번역의 목적은 사용자가 영상 내용을 이해하도록 돕는 데 있으니, 이해에 필요한 텍스트는 번역하되 시청에 방해되는 요소는 최소화해야 합니다.

같은 단어라도 본문에 있으면 번역 대상이고 코드 블록 안에 있으면 아니므로, 단순 규칙만으로는 구분할 수 없습니다. 그래서 화면의 맥락을 얕게나마 이해할 수 있는 VLM(Vision Language Model, 이미지를 입력으로 받아 언어로 추론하는 모델)에 이 판단을 맡겼습니다.

translate-target

나. 문단을 파악한다

대부분의 OCR은 텍스트를 줄 단위 조각으로 반환합니다. 현대 OCR은 주로 텍스트 검출(detection)과 텍스트 인식(recognition)의 2단계 파이프라인으로 구성되는데, 검출기가 찾는 것이 줄 단위이기 때문입니다.

줄 단위 조각이 문제가 되는 이유는 언어별 어순 차이 때문입니다. 한 문장이 여러 줄에 걸쳐 있으면, 어순이 다른 언어로 번역했을 때 결과를 원래 줄과 1:1로 대응시킬 수 없습니다. 한 문단을 하나의 블록으로 묶고, 번역도 그 블록 자리에 통째로 그려야 자연스러운 대응이 가능합니다.

이미지나 PDF에서 화면 구조를 파악 후 문단 레이아웃을 판단하는 작업은 Document Layout Analysis라는 이름으로 이미 연구되어 온 분야입니다. 그래서 기존 모델들을 먼저 시도해 봤지만 영상 번역에 적용하기엔 만족스럽지 못했습니다. 대부분 PDF 문서 이미지로 학습된 모델이라, 강의 영상에 흔히 나오는 웹사이트나 터미널 화면처럼 문서 규격을 벗어난 레이아웃에서는 블록을 엉뚱하게 나누는 것으로 보였습니다.

XY Cut 알고리즘 개념도
도표는 XY-Cut++ (arXiv:2504.10258)를 참고

그래서 문단 판단도 VLM에 맡기되, 판단할 요소를 최소한으로 줄여 정확도를 보조하도록 했습니다. 1984년에 제안된 XY Cut 알고리즘으로 화면을 큼직한 블록으로 먼저 잘라두면, VLM은 그 블록들을 문단으로 묶을지만 판단하면 됩니다.

XY Cut은 화면의 여백 기준상 영역을 가로, 세로로 번갈아 재귀 분할하는 방식으로, 좌표 계산만으로 동작하여 비용이 사실상 없습니다. 분할 결과는 트리 구조로 남는데, 나뉜 영역들을 위에서 아래로, 왼쪽에서 오른쪽으로 차례로 방문하면 그 방문 순서가 사람이 읽는 순서와 대체로 비슷해집니다. 덕분에 블록 안의 여러 줄을 하나의 문단으로 이어 붙일 때도 별도 정렬 없이 그대로 쓸 수 있습니다.

프레임 처리 최적화

여기까지는 화면 한 장을 처리하기 위한 고려였습니다. 그런데 영상은 화면 한 장이 아닙니다. 1초에 1프레임씩만 샘플링해도 1시간 영상이면 3,600장이므로, 다량의 영상을 모두 이 방식으로 처리하기엔 부담이 있죠.

매 장마다 OCR과 VLM을 돌리면 비용도 문제지만, 더 큰 문제는 일관성입니다. 같은 슬라이드가 화면에 떠 있는 동안에도 프레임마다 OCR 결과가 미세하게 흔들리면, 오버레이가 재생 중에 깜빡이게 됩니다.

기본 구조는 매 프레임마다 OCR을 돌려 텍스트 박스를 얻고, 각 박스를 VLM으로 판정하는 것입니다. 여기에 직전 프레임과 겹치는 부분은 다시 처리하지 않고 결과를 재사용하는 방식을 적용했습니다. 새 프레임의 각 텍스트 박스는 아래 순서로 판단 후 처리됩니다.

  1. 픽셀 기반 재사용
    직전 프레임과 해당 영역의 픽셀이 거의 동일하면, OCR도 VLM도 다시 돌리지 않고 이전 결정을 그대로 씁니다. 정적인 슬라이드 구간에서는 이 처리만으로 많은 프레임이 스킵됩니다.

  2. 영역 기반 재사용
    위치가 조금 달라졌어도 기존 영역과 IoU(겹침 비율)가 0.5 이상이고 텍스트 유사도가 0.85 이상이면 이전 결정을 재사용합니다. 화면이 살짝 스크롤되거나 인코딩 노이즈가 존재하는 경우는 흡수됩니다.

  3. 자동 제외
    신규 박스 중 번역할 문자가 없는 것(예: 숫자와 기호뿐인 박스)은 모델 호출 없이 제외합니다.

  4. VLM 판정
    여기까지 살아남은 신규 박스만 VLM 모델로 처리합니다.

이때 OCR에는 원본 프레임을 그대로 넣지 않고 재사용으로 확정된 영역을 마스킹하여서, OCR은 새로 나타난 글자만 검출하도록 하고 있습니다. 이 구조 덕분에 VLM 호출은 화면이 실제로 바뀌는 순간에만 발생하고, 같은 슬라이드가 떠 있는 동안에는 이전 결과가 그대로 유지되어 오버레이도 안정적으로 보여집니다.

텍스트 색 추출

글자를 어디에 그릴지는 정해졌으니, 이제 어떤 색으로 그릴지를 생각해 봐야 합니다.

배경이 대부분 단색에 가깝다고 가정하면, 배경과 글자의 색은 박스 내부 픽셀의 색 분포를 계산해 쉽게 얻을 수 있습니다. 픽셀을 샘플링한 후 RGB 공간에서 색을 유사한 두 그룹으로 분류해둔다면 픽셀 수가 많은 그룹을 배경, 적은 쪽을 글자로 추론할 수 있기 때문입니다. 글자는 배경보다 차지하는 면적이 대부분 작으니까요.

그룹을 나누기 위한 방식으론 k-means(k=2)를 사용합니다. k-means는 데이터를 k개의 군집, 다시 말해 k개의 클러스터로 나누는 알고리즘입니다. 이 알고리즘은 대략 아래처럼 동작합니다.

  1. 먼저 중심점 k개를 아무 위치에나 찍습니다.
  2. 각 점은, 그 점에서 가장 가까운 중심점과 같은 편으로 분류합니다.
  3. 그다음 중심점을 자기 소속 점들의 평균 위치로 옮깁니다.
  4. 중심점이 움직였으니 소속이 바뀌는 점이 생깁니다.
    따라서 2번으로 돌아가, 더 이상 소속이 바뀌지 않을 때까지 2~3을 반복합니다.

이러한 반복 단계를 거치다보면 가까운 점들끼리 묶인 k개의 무리가 안정적으로 만들어집니다. 여기서는 픽셀의 RGB 값이 곧 3차원 공간의 좌표가 되어 색이 비슷한 픽셀끼리 자연스럽게 묶어줄 수 있습니다.

kmeans-cluster

단색 배경 텍스트 박스 하나를 처리한다면 배경 픽셀, 글자 픽셀이 위 그림처럼 각각 뭉치게 됩니다. 위 사진에서는 흰색이 배경, 초록색이 글자색으로 생각할 수 있겠습니다.

번역 및 최종 결과

이제 마지막으로 남은 단계는 번역입니다. 번역은 화면 처리가 모두 끝난 뒤에 따로 진행합니다. 앞 단계에서 만든 JSON에서 원문 텍스트를 모아 중복을 제거하고, LLM(대규모 언어 모델)에 한꺼번에 번역을 요청한 뒤 결과를 각 텍스트에 다시 채워 넣습니다. 같은 문구가 여러 화면에 반복해서 나와도 번역은 한 번만 하면 됩니다.

강의 화면의 텍스트는 제목이나 라벨 같은 짧은 조각이 많아서, 조각만 따로 번역하면 용어가 제각각이 되기 쉽습니다. 그래서 영상 제목과 같은 화면의 주변 텍스트를 프롬프트에 함께 넣어, 같은 용어가 늘 같은 번역으로 나오게 했습니다. 이때 텍스트는 앞서 XY Cut이 정리해 준 읽는 순서대로 나열해서, LLM이 사람이 화면을 읽는 순서 그대로 맥락을 파악하게 했습니다.

아래는 지금까지의 과정을 모두 거친 최종 결과물입니다. 이제 플레이어에서 화면 언어를 선택하면, 원본 영상은 그대로 재생되면서 화면 속 글자만 선택한 언어로 덮어씌워져 보입니다.

화면 번역 적용 전후 비교
화면 번역 적용 전과 후 예시

마무리

지금까지 인프런이 영상 화면 번역 기능을 만들며 하고 있는, 그리고 지금까지 정리된 고민들을 소개드렸습니다. 글을 마무리하며 짧게 되짚어 보겠습니다.

  • 번역 결과는 영상에 인코딩하지 않고, 원본 화면 위에 배경색 박스와 번역 텍스트를 겹쳐 그리는 오버레이 방식으로 보여줍니다.
  • 화면 속 텍스트는 OCR로 읽고, 번역 대상 선별과 문단 묶기는 XY Cut과 VLM의 조합으로 해결했습니다.
  • 프레임 간 겹치는 영역은 이전 결과를 재사용해 처리 비용을 줄이고 오버레이 깜빡임을 막았습니다.
  • 글자색과 배경색은 k-means로 픽셀을 두 그룹으로 나눠 추출하고, 번역은 화면 처리가 끝난 뒤 주변 맥락을 담아 한꺼번에 요청합니다.

물론 아직 모든 화면을 완벽하게 번역하지는 못합니다. 사진이나 그라데이션 위에 놓인 글자는 결과물이 아직 어색하게 나오는 상태이고, 애니메이션으로 움직이는 글자는 오버레이가 미처 따라가지 못하기도 합니다. 이렇게 다듬어야 할 부분이 아직 많이 남아 있어 하나씩 개선해 나가려 합니다.

학습이 언어 때문에 가로막히지 않도록, 그리고 더욱 다양한 지식들이 공유되고 전달될 수 있도록 인프런에서는 다양한 도전을 계속해 나갈 예정입니다.

읽어주셔서 감사합니다.


참고 링크