와우자 StreamPublisher: 파일과 스케줄로 라이브 OTT 채널 만들기

복잡한 방송 시스템, OBS같은 프로그램 없이도 라이브 OTT 채널 송출이 가능하다. 와우자의 StreamPublisher, HTTP Provider, Server Listener 조합으로 파일 라이브 스트리밍 구성하는 방법

A smiling server wearing black sunglasses in server room. Video tapes and television are in front of it.

OTT 라이브 채널을 별도로 구축해야 하는 이유와 방법

저작권과 판권

생각보다 많은 TV 방송사 (채널사용사업자,PP)가 OTT를 이용한 실시간 방송보기 서비스를 제공하지 않는다. 특히 외부에서 콘텐츠를 구매해 사용하는 곳일 경우 유튜브와 같은 플랫폼은 커녕 홈페이지나 어플등에서조차 찾아보기 어려운 경우가 많다. 여러가지 이유가 있겠지만, 대표적인 이유 중 하나는 바로 저작권(판권)이 없기 때문이다.

보통 콘텐츠 제작사는 콘텐츠를 판매할 때 플랫폼별 권한을 구분한다. 만약 방송사가 TV 판권만을 구매했다면, 콘텐츠를 실시간 OTT 로 서비스 하는 것은 콘텐츠 무단사용의 경우에 해당된다.

물론, 모든 콘텐츠의 전체판권을 구매하거나, 저작권에 문제가 생기지 않을 자체제작 콘텐츠로만 편성한다면 문제가 없으나 결국 예산이 문제가 된다.

설비투자와 운용비

그렇기 때문에 라이브 OTT 채널을 운용하기 위해서는 OTT 송출에 문제가 없는 콘텐츠만 편성하는 별도의 채널을 운영해야 할 필요가 있다. 문제는 결국, 새로운 채널을 하나 더 운용하는 개념인지라, 아래와 같은 신규 채널 구성 수준의 비용이 들어간다는 것이다. 전통적인 방송 업계에서 이는, 수천~수십억원의 비용이 추가되는 것을 의미한다.

  • 설비투자 : 송출서버, 인프라, 자막기, 모니터 시스템 등의 설비와 공간
  • 운용비용 : 콘텐츠 관리, 편성 운용 등을 위한 인력

스트리밍 서버로 채널 운영하기

TV 방송 채널은 대부분 준비된 콘텐츠들을 편성에 따라 재생하는 방식으로 운영된다. 한마디로 본 필자가 후배들에게 하는 표현을 빌어 말하자면,

시간 맞춰서 동영상 파일 돌리는 거다. 그게 다다..
EQMaker

와우자 스트리밍 엔진(Wowza Streaming Engine, 이하 와우자)는 이런 상황에 유용한 기능을 모듈 형태로 제공한다. 스케줄에 따라 콘텐츠를 재생하고, 스케줄의 추가나 갱신도 가능하다. 자막과 같은 추가 고려 사항도 있겠으나, 이들 또한 대부분 와우자 엔진을 통해 해결할 수 있다. 즉, 스트리밍 서버만으로 복잡한 송출 시스템이나 실시간 인코더 없이 ‘라이브 TV 채널’을 운영할 수 있다는 것이다.

이러한 방식은 판권 문제로 별도의 채널을 운영해야 하는 방송사에게 효과적인 해결책이 될 뿐만 아니라, 적은 비용으로 라이브 채널을 시작하려는 개인이나 소규모 사업자에게도 훌륭한 선택지가 되어 준다. 본 글에서는 이러한 기능을 구현하는 StreamPublisher 모듈을 설치하고 와우자 어플리케이션에 적용해 실행하는 방법과, 실제 스케줄을 작성하고 적용하는 방법, 그리고 HTTP를 통해 스케줄을 갱신하는 방법에 대해 설명한다.

streampublisher 모듈 설치 및 설정

streampublisher 모듈은 외부 명령을 받아 와우자를 실시간으로 제어해 주는 모듈이므로, 모듈 설치 외에, 추가적으로 서버 리스너와 HTTP Provider를 함께 설정해 주어야 한다.

Step 1 : StreamPublisher 모듈 다운로드 및 설치

  1. StreamPublisher 을 찾아 모듈 파일을 다운로드 받는다. (와우자 스트리밍 엔진 확장 모듈 목록 참고)
  2. 다운로드 받은 확장 모듈의 압축을 풀고 와우자 서버에 설치한다. (와우자 스트리밍 엔진 확장 모듈 설치 방법 참고)
  3. 적용할 어플리케이션의 설정파일인 Application.xmlModule섹션에 아래 내용을 등록해 준다.(와우자 속성 변경 방법 참고)
    모듈 등록 정보
    NameDescriptionFully Qualified Class Name
    streamPublisher스케줄 및 재생목록com.wowza.wms.plugin.streampublisher.ModuleStreamPublisher
    <Module>
      <Name>streamPublisher</Name>
      <Description>스케줄 및 재생목록</Description>
      <Class>com.wowza.wms.plugin.streampublisher.ModuleStreamPublisher</Class>
    </Module>
  4. 와우자 엔진 서비스를 재시작해 준다. (어플리케이션만 재시작 해 주면 모듈 적재가 되지 않는다.)

Step 2 : 서버 리스너(Server Listener) 구성

StreamPublisher 모듈은 시간에 따라 와우자 엔진을 제어해 주는 모듈이다. 즉, 와우자 엔진이 StreamPublisher 모듈의 명령을 받을 수 있도록 서버 리스너를 구성해 주어야 한다. 서버 리스너 클래스 등록을 참고하여 아래의 클래스 명을 등록한다.

com.wowza.wms.plugin.streampublisher.ServerListenerStreamPublisher

Step 3 : HTTP provider 구성

HTTP를 통해 스케줄 파일 갱신, 읽기, 중지 동작을 제어하기 위해 HTTP provider를 구성해 준다.

  1. 와우자 설치 경로/conf/에 위치한 VHost.xml 파일을 텍스트 에디터로 연다.
  2. Default Admin 섹션 (8086 포트)의 HTTPProviders 섹션에 아래의 강조 표시된 항목을 추가하고 저장한다.
    <?xml version="1.0" encoding="UTF-8"?>
    <Root version="2">
     <VHost>
     <HostPortList>
     <HostPort>
     <Name>Default Admin</Name>
     (... 중략 ...)
     (... 중략 ...)
     <HostPort>
      <Name>Default Admin</Name>
     (... 중략 ...)
      <HTTPProviders>
       <HTTPProvider>
        <BaseClass>com.wowza.wms.plugin.streampublisher.HttpProviderStreamPublisherControl</BaseClass>
        <RequestFilters>schedules*</RequestFilters>
        <AuthenticationMethod>admin-basic</AuthenticationMethod>
       </HTTPProvider>
       (... 생략 ...)
  3. 와우자 엔진 서비스를 재시작해 준다.

사용할 어플리케이션에 모듈 적용

설치된 ModuleStreamPublisher를 적용할 와우자 어플리케이션에 아래 프로퍼티들을 추가시켜 준다. (와우자 프로퍼티 추가 방법 참고)

ModuleStreamPublisher 속성
PathNameTypeValue
/Root/ApplicationstreamPublisherSmilFileString재생목록 파일
<Property>
  <Name>streamPublisherSmilFile</Name>
  <Value>sch.smil</Value> // 스케줄 파일로 사용할 smil 파일 이름
  <Type>String</Type>
</Property>

위의 필수 속성을 포함해, 추가 옵션으로 사용할 수 있는 속성들의 목록은 와우자 공식 문서를 참고하기 바란다.

속성을 저장한 후, 해당 어플리케이션을 재시작 하면 모듈이 적용된다.

스케줄 파일 작성

스케줄 파일.smil 확장자를 가진다. 스케줄 파일용 SMIL 파일은 ABR 스트림 구성을 정의하는 파일과는 다른 형식과 구조를 가진다. 텍스트 에디터를 이용해 아래와 같이 스케줄 파일을 작성하면 된다.

<smil>
 <head>
 </head>
  <body>
   <stream name="Channel1"></stream>
   <stream name="Channel2"></stream>
   <playlist name="CH1PL1" playOnStream="Channel1" repeat="true" scheduled="2025-04-15 10:00:00">
    <video src="mp4:BBB_1500kbps.mp4" start="0" length="15"/>
    <video src="mp4:Gasi_1500kbps.mp4" start="50" length="15"/>
   </playlist>
   <playlist name="CH2PL1" playOnStream="Channel2" repeat="true" scheduled="2025-04-15 10:00:00">
    <video src="mp4:BBB_1500kbps.mp4" start="0" length="15"/>
   </playlist>
  </body>
</smil>
stream 태그
스케줄 파일이 생성할 스트림을 정의한다. 복수의 스트림도 생성 가능하다.
name
이 스케줄 파일이 생성할 스트림의 스트림 네임을 지정
playlist 태그
재생 목록의 스케줄과 재생 방법을 정의한다.
name
재생 목록을 구분하기 위한 이름
playOnStream
재생 목록이 재생될 스트림 이름
repeat
재생 목록의 반복여부. false로 설정 할 경우, 재생 목록이 종료되면 스트림도 종료된다.
scheduled
재생 목록의 재생을 시작할 시각.
video 태그
각 콘텐츠 파일의 재생방법을 정의한다.
src
프리픽스와 함께 재생할 파일명을 적는다
start
콘텐츠의 시작 지점을 정의한다. 예를 들어, 2는 처음 2초 지점부터 재생을 시작한다는 의미이다. 라이브 스트림을 소스로 사용할 경우 -2를 입력해 준다. 처음부터 재생할 경우, 0을 입력해 준다.
length
콘텐츠의 재생시간을 정의한다. 예를 들어, 15는 재생 시작으로부터 15초만 재생하고 다음 콘텐츠로 넘어간다는 의미이다. 콘텐츠의 끝까지 재생 하고자 할 경우, -1를 입력해 준다.

이렇게 작성한 스케줄 파일과 재생에 사용할 콘텐츠 파일을 content 디렉토리에 업로드 해 준다.

스케줄 파일 작성에 대한 추가적인 내용은 와우자의 공식 문서를 참고하기 바란다.

HTTP를 이용한 스케줄 파일 적용

HTTP 프로바이더를 통해 스케줄 제어를 하기 위해 curl 또는 웹브라우저를 이용하여 다음과 같이 요청을 전송한다. (REST API 외부 접속 설정 및 curl 사용법 참조)http://[서버IP]:8086/schedules?appName=[어플리케이션 네임]&action=[요청 액션]

윈도우 환경에서 curl 을 사용할 경우 아래의 예와 같이 입력해 주면 된다.

C:\>curl -u decteng:dectengpw "http://blogdemo.decteng.com:8086/schedules?appName=FileToLive&action=loadSchedule" // 요청
<html><head><title>loadSchedule</title></head><body>FileToLive/_definst_ : loadSchedule : DONE!</body></html> // 응답

위의 예에서 보인 윈도우 curl의 각 파라메터의 의미는 다음과 같다.

-u 옵션
curl 에서 사용자 인증을 위한 ID 와 암호를 전달하는 옵션. ID : decteng / PW : dectengpw 를 사용했다.
appName
스케줄을 로드할 어플리케이션의 이름
action
요청하는 동작의 종류
  • loadSchedule : 스케줄 적재
  • reloadSchedule : 스케줄 재 적재(현재 재생중인 스케줄이 있을 경우에 유효)
  • unloadSchedule : 적재된 스케줄 해제 (재생 중지)

스케줄에 따른 재생은 다음 규칙에 따라 이루어진다.

  • 새 스케줄의 시작시각이 지났을 경우 : 플레이리스트 즉시 시작
  • Idle 상태, 스케줄의 시작 시각 전일 경우 : 스트림은 생성되지만 출력은 null 상태로 대기하다 지정시각에 재생을 시작
  • 재생중, 새 스케줄 시작 시각 전일 경우 : 기존 스케줄을 계속 진행하며, 새로운 스케줄의 시작시각에 맞춰 재생이 시작된다.

HTTP provider를 통한 추가적인 요청 항목은 와우자 공식 문서를 참고하기 바란다.

주의사항

StreamPublisher 모듈을 사용할 때 주의할 점은 다음과 같다.

최소 콘텐츠 길이
재생 목록에 추가된 콘텐츠의 길이가 너무 짧을 경우, 와우자 엔진의 동작이 불안정해 질 수 있다.
본 필자의 경험상, 최소 15초 이상의 콘텐츠를 사용 하는것을 권한다.
콘텐츠 형식 통일
콘텐츠의 형식을 혼합해 사용할 경우 클라이언트의 상황에 따라 디코딩이 중단될 수 있다. 다시 재생하면 정상적으로 돌아오지만, 연속적인 시청 경험에 매우 좋지 않은 영향을 끼친다.
비디오 스트림의 디코딩이 깨진 화면. 화면의 어떤 객체도 식별할 수 없으며, 얇고 깨진 그라데이션만 표시됨.
다른 포맷의 파일으로 전환될때의 모습
라이브 스트림
라이브 스트림의 경우, 해당 어플리케이션이 라이브 소스에 연결된 상태여야 한다.
지연시간
초 또는 밀리초 단위로 스케줄을 작성할 수 있지만, 적용 시 1~2초의 지연시간이 발생할 수 있다.
서버 보안
본 예제에서는 기능 구현에 집중하고자 HTTP provider 사용자 인증을 admin-basic로 설정했다.
https 를 사용하지 않거나, 방화벽이 없을 경우 보안 문제가 발생할 수 있다. 관련내용은 와우자의 공식 메뉴얼을 참고하기 바란다.

마무리

Wowza Streaming Engine의 StreamPublisher 모듈은, 정해진 콘텐츠를 원하는 시간에 자동으로 송출할 수 있도록 도와주는 유용한 도구이다. 본 글에서는 매우 기본적인 설정과 개념만을 다뤘지만, 별도의 송출 시스템 없이, 콘텐츠를 실시간 방송처럼 제공할 수 있는 기능은 그 활용에 따라 매우 다양한 방법으로 응용이 가능하다.

StreamPublisher 모듈에 대한 추가적인 내용은 와우자의 공식 문서를 참고하기 바란다.

요약과 FAQ

와우자 StreamPublisher 모듈을 이용해 라이브 채널을 구축할때의 장점은?
OBS등과 같이 지속적인 인코딩 컴퓨팅 파워가 필요하지 않으며, 별도의 송출서버나 방송시스템이 필요하지 않아 비용을 절감할 수 있다.
TV채널의 실시간 방송보기 서비스가 없는 이유는?
여러 이유가 있으나, 저작권(판권)문제로 인해 정규 TV 신호를 OTT로 재전송 하는것이 불가한 경우가 많다.
스트리밍 서버를 이용해 생방송도 송출이 가능한가?
가능하지만, StreamPublisher 외에 다른 모듈들을 추가로 결합하는 것이 필요하다.
채널사용사업자(PP)란?
“지상파방송사업자·종합유선방송사업자 또는 위성방송사업자와 특정 채널의 전부 또는 일부 시간에 대한 전용사용계약을 체결하여 그 채널을 사용하는 사업”(방송법 제2조)을 하는 자로, 흔히 ‘TV 채널’ 또는 ‘방송국’으로 불리는 사업자들을 말한다.
스케줄의 갱신방법은?
스케줄 파일을 업로드한 후 REST API를 이용해 갱신 요청을 전달하면 새로운 스케줄이 적용된다.
스케줄 파일의 시간 정확도는?
스케줄 설정은 밀리초 단위로 가능하지만, 실제 정확도는 2~3초 단위의 오차가 있을 수 있다.
비슷한 다른 솔루션은?
미디어계의 맥가이버칼 ffmpeg을 비롯해, OBS나 Prism, vMix등의 통해서도 비슷한 기능을 구현할 수 있다.
스트리밍할 미디어 파일의 최소 권장 길이가 있는가?
너무 짧은 파일이 반복되서 로드될 경우 오작동하는 경우가 있다. 와우자에서는 10초 이상의 콘텐츠를 사용할 것을 권하고 있으며, 본 필자의 경험상 최소 5초 이상은 되어야 정상적인 동작이 가능하다.
여러 콘텐츠 파일을 사용할 경우 주의 사항은?
여러 콘텐츠 파일을 사용할 때 각 파일의 포맷 (코덱, 해상도, FPS 등)이 동일해야 한다. 각 파일을 재생할 때 스트림의 규격이 달라지게 된다. 이는 클라이언트의 연속적인 시청 경험에 나쁜 영향을 미친다.

1998년 라이브 음향 엔지니어로 시작해 2005년부터 방송 송출 및 미디어 전송 엔지니어의 삶을 살아가고 있습니다. 아날로그 제작 시스템부터 최신 IP 미디어 라스트마일 환경까지, 미디어 기술과 정보 통신 기술(ICT)의 융합을 통해 새로운 솔루션을 제안하고 실현시켜 왔습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Post comment