vMix 강의 14편 | 트리거·스크립팅·API: vMix 자동화 입문
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
이 강의를 마치면 "영상이 끝나면 카메라로 돌아가고 자막을 올려 줘" 같은 일을 손 대신 vMix가 하게 만들 수 있습니다. 버튼 하나에 담기 어려운 동작은 스크립트로, 외부 프로그램이나 웹페이지에서 vMix를 조작하는 일은 API로 해결하는 기준이 생깁니다.
이 글은 vMix 강의 시리즈 14편입니다. 이전 편: 쇼트컷과 컨트롤 서피스: 키보드, Stream Deck, MIDI, 태블릿 · 다음 편: 크로마키와 가상 세트: 작은 공간에서 스튜디오처럼
세 방법은 이렇게 나뉩니다.
| 방법 | 언제 | 어디서 | 에디션 |
|---|---|---|---|
| Triggers | 입력에 일어난 일에 반응 (Program에 올라감, 영상 끝남) | 입력 설정 → Triggers 탭 | 전 에디션 |
| Scripting | 조건·반복·대기가 필요한 동작 | Settings → Scripting | 4K·Pro·MAX |
| API (HTTP/TCP) | 외부 프로그램·웹페이지·장치에서 vMix 조작 | Settings → Web Controller 탭 | 전 에디션 |
1. Triggers: 입력이 Program에 올라갈 때, 영상이 끝날 때

입력 속성 → Triggers 탭. 이 입력이 Program에 올라가거나 재생이 끝날 때 실행할 기능을 줄 단위로 넣습니다.
입력의 설정 창(입력 이름 옆 톱니 또는 더블클릭)에서 Triggers 탭을 열면 "이 입력에 어떤 일이 일어나면 무엇을 하라"는 목록을 만들 수 있습니다. 쇼트컷이 사람이 버튼을 누르는 것이라면, 트리거는 입력이 버튼을 누르는 것입니다. 이벤트는 다음과 같습니다.
- OnTransitionIn / OnTransitionOut: 입력이 Program으로 들어가기 시작할 때 / 나가기 시작할 때
- OnOverlayIn / OnOverlayOut: 입력이 오버레이로 올라갈 때 / 내려갈 때
- OnCompletion: 영상·List·Photos·PowerPoint 입력이 끝까지 재생됐을 때 (Loop가 꺼져 있어야 함)
- OnPlaybackTime / OnPlaybackRemaining: 재생 위치가 지정한 시각에 닿을 때 / 남은 시간이 지정 값이 될 때
- OnCountdownCompleted: 타이틀의 카운트다운이 0이 될 때
- OnVideoCallConnected / Disconnected: vMix Call 게스트가 붙거나 떨어질 때
- OnReplayEventsCompleted: 리플레이 이벤트 재생이 끝났을 때
- OnZoomActiveSpeaker 계열: Zoom 입력에서 발언자가 바뀔 때
각 줄에는 Function, Input, Duration, Delay를 넣습니다. 같은 이벤트의 줄은 위에서부터 차례로 실행되고 Delay는 "앞 줄 다음에 몇 ms 기다렸다가"입니다. 예를 들어 영상 입력에 OnTransitionIn으로 "1초 뒤 OverlayInput1로 제목 자막 올리기, 5초 뒤 내리기"를 걸면, 영상이 Program에 들어갈 때마다 제목이 떴다 사라집니다. 쇼트컷으로 만들면 매번 눌러야 하지만 트리거는 잊지 않습니다.
제한 두 가지가 중요합니다. 첫째, **Delay는 최대 30초(30000 ms)**입니다. 그 이상은 30초로 잘리고, 긴 흐름은 PlayList나 스크립트로 하라고 공식 문서가 안내합니다. 둘째, OnTransitionIn·OnTransitionOut에서는 트랜지션 함수가 동작하지 않습니다. 무한 루프를 막기 위한 설계입니다. 또 트리거는 Program에 있는 주 입력에서만 발생하고, 레이어로 들어 있는 입력은 OnCompletion을 제외하면 발생하지 않습니다. OnCountdownCompleted와 OnPlaybackTime은 입력이 어디에 있든 발생합니다.
2. Scripting(VB.NET) 기초: API 호출, 대기, 조건문

Settings → Scripting. 스크립트 목록과 편집 창입니다(4K 에디션 이상).
Scripting은 4K·Pro·MAX에서 Settings → Scripting 탭에 있습니다. 스크립트에 고유한 이름을 붙여 저장하고, 쇼트컷 함수 ScriptStart에 그 이름을 적어 버튼이나 트리거에서 실행합니다. 쇼트컷처럼 **Local Script (This Preset Only)**로 프리셋에 묶을 수 있고, 같은 이름이 둘이면 목록의 첫 번째가 실행됩니다.
언어는 VB.NET과 Web Scripting 두 가지입니다. Web Scripting은 API 호출을 한 줄씩 적는 것이라 가장 쉽습니다.
Function=SetText&Input=Lower3rd.gtzip&SelectedName=Name.Text&Value=홍길동
Function=OverlayInput1In&Input=Lower3rd.gtzip
Sleep 4000
Function=OverlayInput1Out
VB.NET은 Sub 하나 안에서 쓸 수 있는 코드라고 생각하면 됩니다. 사용자 클래스는 안 되지만 .NET 기본 클래스는 대부분 되고, 자주 쓰는 vMix 객체는 네 개입니다. Input.Find("이름")과 Input.Output, Input.Preview로 입력을 잡고, .Text("필드.Text")로 타이틀 글자를 읽고 쓰며, .Function("Cut")로 어떤 쇼트컷 함수든 호출합니다. Overlay.Find(1).In("이름"), .Out, .Off로 오버레이를 다루고, API.XML()로 현재 상태 XML을 읽고 API.Function("CubeZoom",,1000)처럼(공식 문서의 예시) API를 직접 부릅니다. Sleep(ms)로 기다리고, Console.WriteLine은 Scripting 탭의 콘솔에 글자를 찍어 디버깅합니다. 그 위에 If, For, Do While 같은 일반 VB.NET 문법이 얹힙니다.
제가 실제로 돌리는 스크립트 다섯 개입니다.
- 영상 재생 후 복귀: Preview에 올린 영상을 Cut으로 내보내고
Input.Output.WaitForCompletion(600000)으로 끝날 때까지 기다린 뒤Input.Find("Cam1").Function("Fade", , 500). OnCompletion 트리거와 같은 일을 하지만 중간에 조건을 넣을 수 있습니다. - 자막 띄웠다 내리기:
Overlay.Find(1).In("Lower3rd.gtzip")→Sleep(5000)→Overlay.Find(1).Out. 자막마다 트리거를 걸지 않아도 됩니다. - 녹화 확인 후 시작:
API.XML()을 읽어<recording>값이 False면API.Function("StartRecording"). 방송 시작 버튼 하나에 "녹화 안 켜져 있으면 켜기"를 넣습니다. - 웹에서 글자 가져오기:
System.Net.WebClient로 텍스트를 내려받아Input.Find("Score.gtzip").Text("Home.Text")에 넣기. 외부 타이머나 점수 서버와 연동할 때 씁니다. - 모든 오버레이 끄기:
For i = 1 To 8 : Overlay.Find(i).Off : Next. 비상용 버튼입니다.
3. vMix API(HTTP/TCP): 외부에서 vMix 조작하기, XML 상태 읽기

Settings → Web Controller. HTTP·TCP API 접근 권한과 포트는 여기서 확인합니다.
HTTP API는 Web Controller와 같은 주소를 씁니다. 브라우저에 다음을 치면 Preview가 1초 Fade로 Program에 들어갑니다.
http://127.0.0.1:8088/api/?Function=Fade&Duration=1000
쇼트컷의 Function 드롭다운에 있는 함수는 전부 이렇게 부를 수 있습니다. Input은 번호(0은 Preview, -1은 Program), 이름(대소문자 구분, 전체 제목), 또는 XML의 key 속성에 있는 GUID로 지정합니다. 이름은 바뀌기 쉽고 번호는 순서에 묶이니 외부 연동에는 GUID가 안전합니다. 타이틀 글자는 Function=SetText&Input=...&SelectedName=Headline.Text&Value=내용으로 바꾸는데, GT 타이틀은 필드 이름 뒤에 .Text(글자)나 .Source(이미지)를 붙여야 합니다. 정확한 필드 이름은 vMix의 Title Editor에 그대로 표시됩니다. 성공하면 200, 실패하면 500을 돌려주고, 파라미터 없이 부르면 vMix 전체 상태가 XML로 옵니다. 어떤 입력이 Program인지, 오버레이에 무엇이 떠 있는지, 녹화·송출 중인지가 모두 들어 있어서 외부 대시보드나 탈리를 만드는 재료가 됩니다.
TCP API는 포트 8099에 붙어 한 줄 명령을 주고받습니다. FUNCTION PreviewInput Input=5처럼 HTTP와 같은 쿼리 문법을 쓰고, XMLTEXT vmix/inputs/input[1]/@title처럼 XPath로 값 하나만 뽑을 수 있어 아두이노 같은 작은 장치에 맞습니다. 가장 유용한 것은 SUBSCRIBE TALLY입니다. 입력별 0(꺼짐)·1(Program)·2(Preview) 문자열이 상태가 바뀔 때마다 밀려 들어오므로 폴링 없이 탈리를 만듭니다. SUBSCRIBE ACTS로는 Activators 이벤트 전체를 받을 수 있습니다.
4. Data Sources + 스크립트로 스코어보드 자동 갱신
스코어보드처럼 "값이 바뀌면 화면도 바뀌는" 일은 스크립트보다 Data Sources가 먼저입니다. 메인 창 오른쪽 아래 메뉴의 Data Sources Manager에서 소스를 추가하는데, Excel/CSV(XLSX·XLS·ODS·CSV·HTML·PDF 표), 누구나 볼 수 있게 공유한 Google Sheets(API 키 필요), RSS, Text 파일, XML(XPath 지정), JSON(객체 배열), Zoom 채팅을 지원합니다. 첫 행이 열 이름이면 Use first row as column names를 켭니다. 그다음 타이틀 필드에 열을 매핑하면 파일이나 시트가 바뀔 때 타이틀도 따라 바뀝니다. 타이틀 쪽 설정은 5편 GT Title Designer에서 다뤘습니다.
스크립트가 끼어드는 지점은 두 가지입니다. 하나는 행 이동입니다. DataSourceNextRow·DataSourcePreviousRow·DataSourceSelectRow 함수를 쇼트컷에 걸면 기록원이 시트 행을 넘기듯 발언자 자막을 넘길 수 있고, 스크립트로는 "행 넘기고 1초 뒤 자막 올리기"처럼 묶을 수 있습니다. 다른 하나는 Data Sources가 못 읽는 형식을 읽어 타이틀에 넣는 경우로, 2절의 4번 스크립트가 그것입니다. 점수판 운영은 시트 한 장을 기록원 폰에서 열어 두고 vMix는 그 시트만 보게 하는 구성이 가장 사고가 적었습니다.
5. 외부 연동 예: 타이머 앱, 큐시트 스프레드시트, 채팅 자막 표시
- 타이머: 발표 시간 타이머를 타이틀의 카운트다운으로 만들고 SetCountdown·StartCountdown을 API로 외부 큐 프로그램에서 부릅니다. 0이 되면 OnCountdownCompleted 트리거로 "시간 종료" 자막을 띄웁니다.
- 큐시트: 구글 시트에 순서·발언자·소속을 적어 Data Source로 연결하고, 운영자는 DataSourceNextRow 버튼만 누릅니다. 큐시트가 바뀌면 시트만 고치면 됩니다.
- 채팅 자막: 유튜브 채팅을 받아 주는 외부 도구가 텍스트 파일이나 JSON을 쓰게 하고, 그 파일을 Text·JSON Data Source로 읽어 타이틀에 매핑합니다. vMix Social처럼 API에 직접 쓰는 프로그램을 쓸 때는 Web Controller 탭의 Allow software on this computer access without login을 켜야 합니다.
- 외부 스위처 버튼: Stream Deck이나 Companion이 하는 일도 결국 이 API 호출입니다. 13편의 장비들이 전부 여기에 얹힙니다.
6. 안전장치: 생방송 중 스크립트 오류 대비, 테스트 프리셋
자동화는 틀리면 틀린 일을 성실하게 반복합니다. 제 안전장치는 다섯 가지입니다.
- 테스트 프리셋을 따로 둡니다. 본방 프리셋을 복사해 트리거와 스크립트를 먼저 돌려 보고, 콘솔에 Console.WriteLine을 찍어 순서를 확인한 뒤 본방 프리셋에 옮깁니다.
- ScriptStop 버튼을 만들어 둡니다. 루프가 도는 스크립트는 이 버튼이 유일한 브레이크입니다. 반복문에는 반드시 Sleep과 탈출 조건을 넣습니다.
- 트리거는 입력 하나에 하나씩. 같은 자막을 OnTransitionIn과 스크립트 양쪽에서 올리면 두 번 뜹니다. 어느 쪽이 담당인지 정해 둡니다.
- API는 LAN 안에서만. Settings → Web Controller 탭의 Restrict access to LAN only는 기본으로 켜져 있습니다. 끄지 말고, 외부 접근이 꼭 필요하면 방화벽 뒤에서 비밀번호와 함께 엽니다. Enable enhanced security on Web and TCP API를 켜면 동적 스크립트 실행이 막혀 더 안전합니다.
- 수동 복귀 버튼은 항상 살려 둡니다. 자동화가 멈췄을 때 Cam1 Fade와 OverlayInputAllOff를 손으로 누를 수 있어야 합니다.
실습 과제
영상 입력 하나와 카메라 입력 하나, 로어서드 타이틀 하나를 준비합니다. 영상 입력의 Triggers 탭에 OnCompletion → Function Fade, Input 카메라, Duration 500을 넣고, 두 번째 줄에 OverlayInput1In, Input 로어서드, Delay 1000을 넣습니다. 영상을 Program에 올리고 끝까지 재생되면 카메라로 돌아간 뒤 1초 후 자막이 올라오는지 확인합니다. 이어서 같은 동작을 Web Scripting 네 줄로 옮겨 ScriptStart 쇼트컷으로 실행해 보고, 마지막으로 브라우저에서 HTTP API로 Fade를 호출해 세 방법이 같은 결과를 내는 것을 확인합니다.
자주 하는 실수
- 트리거가 중복 실행돼 자막이 두 번 뜹니다. 입력 A의 OnTransitionIn과 자막 입력의 OnOverlayIn에 각각 같은 동작을 걸어 두었거나, 스크립트와 트리거가 겹친 경우입니다. 담당을 하나로 정하고 나머지는 지웁니다.
- 스크립트 무한 루프.
Do While True안에 Sleep이 없으면 vMix가 느려집니다. 반복마다 Sleep을 넣고, 탈출 조건을 두고, ScriptStop 버튼을 준비합니다. - API 포트를 외부에 노출합니다. 공유기 포트포워딩으로 8088·8099를 열면 누구나 송출을 끌 수 있습니다. LAN 제한을 유지하고 원격 조작은 VPN으로 합니다.
핵심 요약
- Triggers는 입력 설정의 Triggers 탭에서 OnTransitionIn·OnCompletion 같은 이벤트에 함수를 순서대로 걸며, Delay는 30초가 한계입니다.
- Scripting(4K·Pro·MAX)은 VB.NET 또는 Web Scripting으로 쓰고 ScriptStart 쇼트컷으로 실행하며, Input·Overlay·API 객체와 Sleep이 핵심입니다.
- HTTP API는 8088 포트의 /api/?Function=...이고 파라미터 없이 부르면 상태 XML을 돌려줍니다. TCP API는 8099에서 SUBSCRIBE TALLY로 탈리를 받습니다.
- 값이 바뀌면 화면이 바뀌는 일은 Data Sources가 먼저이고, 스크립트는 행 이동과 특수 형식 읽기에만 씁니다.
- 테스트 프리셋, ScriptStop 버튼, 담당 하나 원칙, LAN 제한, 수동 복귀 버튼이 안전장치입니다.
FAQ
Q1. HD 에디션인데 Scripting이 없습니다. 자동화를 포기해야 하나요? Triggers와 HTTP·TCP API는 전 에디션에서 됩니다. 조건문이 필요하면 외부에서 API를 부르는 작은 프로그램이나 Companion 같은 도구가 스크립트 역할을 대신할 수 있습니다.
Q2. 트리거로 30초 넘게 기다렸다가 동작하게 하려면요? Delay는 30초에서 잘립니다. 긴 흐름은 PlayList로 구성하거나, 스크립트에서 Sleep을 쓰세요. 영상 끝에 맞추는 것이라면 OnPlaybackRemaining이 더 정확합니다.
Q3. 외부 PC에서 vMix 상태를 보려면 뭘 읽어야 하나요? 파라미터 없는 HTTP API 호출이 돌려주는 XML에 active(Program 입력 번호), preview, overlays, recording, streaming이 전부 있습니다. 값 하나만 필요하면 TCP API의 XMLTEXT에 XPath를 넘기는 쪽이 가볍습니다.
질문이나 다른 현장 경험은 Threads로 알려 주세요. 다음 편에 반영하겠습니다.