와우자 서버 리스너를 이용한 파일 기반 라이브 스트림 생성

와우자 스트리밍 엔진을 이용해 OBS와 같은 라이브 인코더나 별도의 트랜스코더 없이 동영상 파일과 음악 파일의 재생 목록을 만들고 pseudo-live 스트림으로 반복 송출하는 방법을 단계별로 설명한다. ServerListener 클래스와 streamDemoPublisher 속성 및 라이브 스트리밍시 주의할 점도 함께 안내한다.

파일 기반 라이브 스트리밍

동영상 플랫폼을 살펴보면 음악 스트리밍 채널같은 24시간 라이브 스트리밍 콘텐츠가 많이 운영되고 있다. 이러한 24시간 라이브 채널은 보통 미디어 플레이어에서 재생목록을 반복 재생하는 오디오 신호나 외부 카메라의 신호를 OBS(Open Broadcaster Software)와 같은 라이브 스트리밍 도구를 이용해 실시간 인코딩하는 방식으로 구성한다.

이러한 방식은 실시간 인코더를 항상 가동해야 하므로 시스템의 자원 소모가 크고, 오류가 발생할 수 있다. 만약 반복되는 콘텐츠일 경우, 콘텐츠를 미리 인코딩한 다음 파일로 저장해 두고 해당 파일을 계속 스트리밍하는 방식으로 구현한다면 시스템의 자원을 절약하고 상대적인 오류의 가능성을 낮출 수 있다.

와우자 스트리밍 엔진(Wowza Streaming Engine, 이하 와우자)은 VOD 서비스 기능을 제공한다. 이 기능을 응용하면 실시간 인코딩 과정 없이 이미 인코딩된 동영상이나 오디오 파일을 실시간 방송처럼 연속적으로 스트리밍하는 pseudo-live 스트림을 생성할 수 있다. 이렇게 생성한 스트림은 반복 재생이 필요한 음악 스트리밍, 간단한 대체 방송 송출용 필러(Filler) 등 다양한 용도로 활용할 수 있다.

본 글에서는 와우자의 서버 리스너(ServerListener) 클래스를 설정하여 콘텐츠 파일 재생목록 기반의 24시간 라이브 스트림을 구성하는 방법을 설명한다.

서버 리스너를 이용한 파일 라이브 스트리밍 구성 절차

본 필자는 3개의 MP3 오디오 파일로 재생목록을 만든 후, FileToLive라는 와우자 어플리케이션을 생성하여 라이브 스트림을 생성하는 과정을 예시로 설명하겠다.

참고로 비디오 파일의 경우도 파일 포맷과 사용할 프리픽스(prefix)가 다를 뿐, 동일한 방법으로 구성할 수 있다.

Step 1 – 사전 준비

구성을 시작하기 전, 아래와 같은 항목들이 먼저 준비되어 있어야 한다.

  • 라이브 어플리케이션

    스트림을 송출하는 데 사용할 와우자 라이브 어플리케이션이 만들어져 있어야 한다.

  • 스트림 생성을 위해 재생할 콘텐츠 파일

    사용 가능한 파일 포맷 형식의 콘텐츠 파일로, 정당한 사용 권한을 가지고 있어야 한다. 복수의 파일을 사용할 경우 파일의 포맷이 동일한 것이 좋다. 여기서 말하는 파일의 포맷이란 단지 확장자를 말하는 것이 아니다. 코덱, 샘플레이트, 해상도, FPS, 프로파일, GOP 사이즈 등 상세 규격을 의미한다.

  • 콘텐츠 파일 업로드

    사용할 콘텐츠 파일을 와우자의 콘텐츠 디렉토리에 업로드해 두어야 한다. 각 기본 콘텐츠 디렉토리 경로는 다음과 같다.

    윈도우
    C:\Program Files\Wowza Media Systems\Wowza Streaming Engine (버전)\content
    리눅스
    /usr/local/WowzaStreamingEngine-(버전)/content

    본 필자는 WinSCP를 이용해 스트리밍에 사용할 1.mp3, 2.mp3, 3.mp3 3개의 파일을 업로드했다.

    와우자 콘텐츠 디렉토리에 1.mp3, 2.mp3, 3.mp3 파일이 업로드된 모습
    콘텐츠 파일 업로드

Step 2 – 서버 리스너 클래스 등록

서버 리스너 클래스(Server Listener Class)는 와우자의 동작을 제어하는 트리거 역할을 한다. 이 클래스는 특정 어플리케이션이 아닌 와우자 서버 전역에서 동작하는 클래스로, 와우자의 동작을 제어할 수 있다.

  1. 와우자 웹 UI에 접속해 상단의 Server 메뉴를 선택하고, 왼쪽에서 Server Setup을 선택한다.
  2. 상단의 Server Listeners 탭을 선택하면 현재 설정된 서버 리스너의 목록이 표시된다.
  3. Edit 버튼을 클릭하고 Add Server Listeners 버튼을 클릭해 서버 리스너 추가 창을 띄운다.
    와우자 Server Setup의 Server Listeners 탭에 등록된 서버 리스너 목록이 표시된 모습
    서버 리스너 목록
  4. Base Class 항목에 com.wowza.wms.module.ServerListenerStreamDemoPublisher를 입력해 주고 Add 버튼을 클릭해 준다.
    와우자 Add Server Listener 창의 Base Class에 ServerListenerStreamDemoPublisher 클래스가 입력된 모습
    서버 리스너 클래스 등록
  5. Save 버튼을 클릭해 클래스가 추가된 것을 확인하고 Restart Now 버튼을 클릭해 와우자 서비스를 재시작한다.
    서버 리스너 목록에 ServerListenerStreamDemoPublisher 클래스가 추가되고 재시작 안내가 표시된 모습
    ServerListenerStreamDemoPublisher 등록 완료

Step 3 – 서버 프로퍼티 등록

서버 프로퍼티(Server Properties)는 와우자 엔진이 동작하는 데 필요한 설정값들을 변경하는 부분으로, 위에서 설정한 서버 리스너가 어떤 방식으로 동작할지 정의하는 부분이다.

  1. 재시작된 와우자 엔진의 웹 UI에 다시 접속한다. Server 메뉴를 선택하고, 왼쪽에서 Server Setup을 선택한 후, Properties 탭을 선택한다. 현재 설정된 와우자 엔진의 설정값들이 표시된다.
    와우자 Server Setup의 Properties 탭에 JMX Remote Configuration과 Custom 항목이 표시된 모습
    프로퍼티 설정 화면
  2. 제일 아래에 위치한 Custom 항목의 Edit 버튼을 클릭해 프로퍼티 추가 메뉴에 진입하면 현재 설정된 사용자 프로퍼티 설정값 목록이 표시된다.
  3. Add Custom Property 버튼을 클릭해 Add Custom Property 창을 열어 아래와 같이 입력해 준다.
    Add Custom Property 창에 streamDemoPublisherConfig의 Path와 Name 및 Type이 입력된 모습
    사용자 프로퍼티 생성
    Path
    /Root/Server
    Name
    streamDemoPublisherConfig
    Type
    String
    Value
    아래, streamDemoPublisherConfig의 Value 설정참고

    Value 항목은 해당 서버 리스너의 동작 방식을 제어하는 가장 중요한 설정값이며, 이에 대한 자세한 작성 방법은 아래 Step 4에서 설명한다.

Step 4 – streamDemoPublisherConfig의 Value 설정

Value는 등록한 streamDemoPublisherConfig 의 동작을 정의하는 부분으로 아래와 같은 형태로 사용한다.

appName=FileToLive,srcStream=m3u8:lst.m3u8,dstStream=MusicBox

이를 각 구성요소별로 분리해 보면 다음과 같이 정리할 수 있다.

프로퍼티
적색 부분, 설정 항목
appName, srcStream, dstStream
청색 부분, 프로퍼티에 적용할 값
FileToLive, m3u8:lst.m3u8, MusicBox
연결자
황색으로 표시된 =는 프로퍼티와 값을 연결해 준다
구분자
둘 이상의 프로퍼티를 선언할 경우 ,로 구분해 준다.

streamDemoPublisherConfig의 프로퍼티 중 자주 사용되는 것과 의미는 다음과 같다.

appName
이 스트림을 생성할 어플리케이션의 이름
dstStream
생성될 스트림의 이름
playlistRepeat
true일 경우 반복 재생, false일 경우 반복 재생 안함
random
true일 경우 재생목록을 무작위로 재생
sendOnMetadata
스트림 시작 시 코덱이나 해상도 등의 메타데이터를 전송
클라이언트가 직접 재생할 경우, 호환성을 위해 true권장
srcStream
스트리밍할 파일 또는 재생목록. 프리픽스를 반드시 지정해야 한다.
timeBetweenItems
재생목록을 재생할 시, 다음 콘텐츠 재생까지 대기 시간

이 형식에 맞춰 아래와 같이 streamDemoPublisherConfig의 Value를 지정할 수 있다.

appName=FileToLive,srcStream=m3u8:lst.m3u8,dstStream=MusicBox,random=false,timeBetweenItems=250
streamDemoPublisherConfig의 Value에 재생목록과 출력 스트림 설정 문자열이 입력된 모습
Value 설정

이 설정에 따라, 와우자는
재생목록 lst.m3u8 파일을 읽고, 재생목록에 기록된 순서에 따라
콘텐츠들을 250ms의 간격으로
연속해서 반복 재생하는 스트림을(명시적으로 playlistRepeat를 선언하지 않았으나 자동 적용된다)
FileToLive라는 이름을 가진 어플리케이션에
MusicBox라는 이름으로 생성하게 된다.

Add 버튼을 클릭해 프로퍼티가 추가된 것을 확인한 후 Save 버튼을 클릭해 적용해 주고 와우자 서비스를 재시작해주면 streamDemoPublisherConfig 설정이 완료된다.

이 글에서는 다루지 않았지만 좀 더 다양한 조건을 지정하기 위한 프로퍼티들이 있다. 와우자 홈페이지에서 제공하는 문서를 참고하기 바란다.

Step 5 – 재생목록 파일의 생성과 업로드

재생목록으로 지정된 lst.m3u8 파일을 생성한다. 일반적인 텍스트 편집기를 이용해 다음과 같이 작성해 주면 된다. 본 필자는 위에서 언급한 3개의 MP3 오디오 파일을 스트리밍하기 위해 mp3: 프리픽스를 사용했다.

mp3:1.mp3
mp3:2.mp3
mp3:3.mp3

생성한 파일을 콘텐츠 디렉토리에 업로드해 준다.

Step 6 – 와우자 서비스 재시작

설정을 완료하고 모든 콘텐츠 파일이 업로드 되었음을 확인한다. 이상이 없다면 설정 변경을 적용하기 위해서 서비스를 재시작해 주어야 한다.

Step 7 – 어플리케이션 확인 (진실의 시간)

  1. 와우자 웹 UI에 접속해 Applications 메뉴를 선택한 후, 좌측의 어플리케이션 목록 중 appName에서 지정한 어플리케이션을 선택한다.
  2. Incoming Streams을 클릭해 스트림이 추가되었는지 확인한다.
  3. 스트림의 비트레이트를 확인0이 아닌지 확인한다.
    FileToLive 어플리케이션의 Incoming Streams에서 MusicBox 스트림의 처리량이 표시된 모습
    라이브 스트림 동작 확인
  4. 최종적으로 VLC 등의 클라이언트를 이용해 스트림을 재생해 본다.

본 글에서 사용한 테스트용 콘텐츠 파일과 Server.xml 파일 및 플레이리스트 파일은 본 필자의 구글 드라이브에서 다운로드 받을 수 있다.

참고 사항

이렇게 생성된 라이브 스트림은 와우자가 종료될때 까지 중단 없이 유지된다. 문제는, 콘텐츠 파일이나 재생목록을 변경하기 위해서는 와우자 서비스 자체를 재시작해 주어야 한다는 것이다. 즉, 와우자의 모든 서비스가 중지되어야 한다는 소리다.

만약, 스트림의 중단 없이 재생목록이나 콘텐츠를 변경하고자 한다면, 본 글에서 설명한 서버 리스너 대신 StreamPublisher모듈을 사용하는 방법이 있다.

FAQ

파일만으로 라이브 스트림을 생성할 수 있는가?
가능하다. 와우자 스트리밍 엔진의 서버 리스너를 이용하면 서버에 저장된 MP3나 MP4 등의 미디어 파일을 라이브 스트림처럼 게시할 수 있다. 원본 파일을 반복 재생하도록 설정하면 외부 카메라나 별도의 실시간 송출 프로그램 없이도 지속적인 파일 기반 라이브 스트림을 구성할 수 있다.
파일 기반 라이브 스트리밍은 일반 VOD와 무엇이 다른가?
VOD는 시청자가 파일의 재생 위치를 선택해 처음부터 보거나 탐색할 수 있는 주문형 방식이다. 파일 기반 라이브 스트리밍은 저장된 파일을 와우자 어플리케이션에 하나의 라이브 스트림으로 게시하므로, 접속한 시점에 현재 송출되고 있는 위치부터 재생한다. 이러한 방식을 pseudo-live 스트리밍이라고도 한다.
와우자 스트리밍 엔진의 서버 리스너(Server Listener)란 무엇인가?
와우자 스트리밍 엔진의 서버 리스너는 엔진의 시작, 종료, 초기화와 같은 서버 이벤트에 반응해 지정된 작업을 수행하는 Java 클래스다. 본 글에서 사용하는 ServerListenerStreamDemoPublisher는 와우자 엔진이 시작될 때 설정된 파일이나 재생목록을 읽고, 이를 라이브 스트림으로 게시한다.
서버 리스너 설정을 변경하면 와우자 스트리밍 엔진을 재시작해야 하는가?
그렇다. ServerListener는 와우자 서비스의 하위 어플리케이션에서 동작하는 것이 아닌, 와우자 서비스 자체에 정의되기 때문이다. 이를 피하려면 streampublisher 모듈과 REST-API 사용을 고려해야 한다.
스트리밍할 미디어 파일의 최소 권장 길이가 있는가?
너무 짧은 파일이 반복돼서 로드될 경우 오작동하는 경우가 있다. 본 필자의 경험상 최소 5초 이상은 되어야 정상적인 동작이 가능하다.
재생목록으로 사용하는 m3u8 파일은 일반적인 HLS 재생목록인가?
아니다. 본 글의 lst.m3u8은 HLS 세그먼트와 재생 시간을 정의하는 일반적인 미디어 플레이리스트가 아니라, 서버 리스너가 순서대로 읽을 콘텐츠 파일 목록이다. 각 줄에는 mp3:1.mp3 또는 mp4:sample.mp4처럼 파일 형식에 맞는 프리픽스와 파일명을 입력한다.
여러 콘텐츠 파일을 스트리밍할 경우 주의 사항은?
여러 콘텐츠 파일을 사용할 때 각 파일의 포맷(코덱, 해상도, FPS 등)이 동일해야 한다. 재생이 불가하지는 않으나 각 파일을 재생할 때 스트림의 규격이 달라지게 된다. 이는 클라이언트의 시청 경험에 좋지 않은 영향을 미친다.
OBS와 같은 송출 프로그램보다 나은 점이 무엇인가?
원본 파일의 코덱과 비트레이트를 그대로 사용하고 Wowza Transcoder를 적용하지 않는다면, 별도의 미디어 플레이어와 실시간 재인코더를 계속 가동하지 않아도 된다. 따라서 파일 디코딩, 화면 합성 및 실시간 재인코딩이 필요한 OBS 기반 구성보다 시스템 자원 사용량과 운영 구성 요소를 줄일 수 있다. 반복 음악 채널, 대기 화면이나 필러처럼 동일한 콘텐츠를 장시간 송출할 때 유용하다.
재생 중인 콘텐츠 파일을 같은 이름으로 교체해도 되는가?
권장하지 않는다. 현재 재생 중인 파일을 직접 덮어쓰면 파일 잠금, 캐시, 파일 크기 변화 또는 미디어 규격 변경으로 인해 재생 오류가 발생할 수 있다. 새 파일을 다른 이름으로 업로드한 뒤 재생목록과 설정을 안전하게 변경하는 방식이 좋다.

갱신 내역

  • 최초 게시
  • 1차 수정
  • 2차 수정, 주소 이전