시놀로지 도커로 치지직 실시간 녹화 프로그램 만들기

시놀로지 도커로 치지직 실시간 녹화 프로그램 만들기

개요

나는 현재 n100 미니PC에다가 시놀로지를 설치해 홈 네트워크로 사용 중이다. n100으로 서버를 구축하면 소비전력이 평균 13w정도밖에 쓰이지 않는다. 한 달 내내 돌린다면 2400원 정도의 전기세 밖에 들지 않는다.

홈 네트워크는 나중에 따로 글을 작성할 예정이다. 이번에는 내가 필요로 하는 프로그램을 이 서버에 돌아가도록 개조하는 과정을 작성할 것이다.

나는 평소에 즐겨 보는 치지직 스트리머가 있다. 하루는 너무 바빠 스트리밍을 놓치는 날도 있고, 그 방송의 vod를 풀지 않을 때도 많이 있었다. 그래서 내가 직접 실시간 녹화를 해보고자 한다.

이미 인터넷에는 나와 같은 생각을 하신 분이 많이 계셨다. 그 중 한 분이 만드신 실시간 녹화 프로그램은 완성도가 꽤 있어 보여서 그 프로그램으로 녹화를 하려고 한다.

직접 다운로드 하기 원한다면, 구글에 내맘대로 치지직Chzzk 자동녹화를 입력하면 나올 것이다.

모 커뮤니티에서 프로그램을 공유하시는 이 분은 스텔라이브 팬이신듯 하다. 프로그램을 실행하자 마자 스텔라이브 멤버들이 도배되어 있었다.

gui, nongui같은 여러 버전이 존재했고 심각한 버그도 없으며 나에게 딱 알맞은 프로그램이지만, 아쉽게도 윈도우 버전이었다.

나는 nongui 버전 py프로그램을 뜯어보았고, 시놀로지에 붙일 수 있을것 같다고 생각해서 한번 도전해 보았다.

계획

일단 시놀로지는 리눅스 기반이다. 나는 이 파이썬파일을 리눅스 환경에 맞게 수정만 하면 될 것 같았다.

먼저 이 프로그램을 어떻게 시놀로지에서 실행시킬까 생각해 보았다.

시놀로지에는 시간에 맞춰 동작을 서비스나 스크립트를 수행하는 스케줄러가 있다.

여기서 간단하게 파이썬 파일을 실행시키도록 구현해도 되지만, 문제는 모니터링을 하기에는 불편한 환경이다.

로그를 확인하기 힘들고 리소스 모니터링은 불가능하다.

그래서 시놀로지에서 제공하는 컨테이너 매니저를 사용해서 이 파일만을 서비스하는 컨테이너를 만들 생각이다.

컨테이너 매니저를 사용한다면 현재 네트워크 사용량이라던지, 실시간으로 로그가 뿌려지는걸 확인하기 쉽기에 시놀로지 다뤄 본 사람이라면 컨테이너 매니저를 자주 써봤을 것이다.

그래서 ssh를 통해 Dockerfile을 build 시키거나 docker-compose를 build해서 컨테이너를 만들어보고자 한다.

환경은 준비되었고, 다음으로 해당 프로그램을 손볼건데 이 파일을 시놀로지에 그대로 갖다 쓰기에는 문제가 많이 있었다. 그래서 마개조가 필요하다.

프로그램 마개조

우리가 개조할 파일은 현재 기준 가장 최신버전인 LITE3d 버전이다. 이 글에서는 LITE3d 버전을 사용하여 설명할 것이다.

해당 파일을 run.py로 이름을 바꿔주자. 나중에 알아보기 편할 것이다.

나머지 버전(.py 파일)은 삭제해도 좋다.

  1. ffmpeg 변경

디렉터리 속에는 인코딩 프로그램인 ffmpeg가 존재하는데 이것을 리눅스 버전으로 갈아 끼워야 한다.

기본적으로는 dependent 폴더 내에 윈도우 버전 ffmpeg가 존재한다.

ffmpeg 공식 사이트에서 리눅스 버전으로 설치해서 기존의 ffmpeg폴더와 바꾸면 된다.

ffmpeg 폴더 내에 이런 파일이 있으면 된다.

여기서 끝이 아니고 소스 코드에서 ffmpeg 실행 디렉토리를 알맞게 수정해야 한다.

빨간불이 켜진 부분을 ffmpeg파일에 맞게 수정하면 된다.

리눅스용 ffmpeg는 .exe가 아닌 ffmpeg 그 자체기 때문에 경로 설정에 주의해야 한다.

  1. 호환되지 않는 코드 수정

소스 코드에는 Windows 전용 속성이 존재했고, 윈도우 디렉토리를 사용한다. 이를 리눅스에 맞게 수정해야 한다.

  • 디렉터리 경로 수정

윈도우와 리눅스는 디렉토리 형식이 다르다. 윈도우는 (드라이브 기호:/directory)이고 리눅스는 (volume1/directory) 이렇게 구성된다.

우선 소스 코드에는 디렉토리 형식을 수정할 부분이 2군데 있다.

녹화파일 저장위치
후처리 최종완료 후 이동 경로

기존에는 "D:/test" 이런식으로 되있지만 우리는 "/app/test/" 이런 식으로 수정하면 된다.

여기서 중요한 것이 있는데, 시놀로지의 로컬 디렉토리가 아닌, 로컬 디렉토리와 매핑된 디렉토리의 이름을 넣어야 한다. 예를 들어 위 수정된 경로 중 app이 마운트된 최상위 디렉토리가 된다. 이건 아래에서 다시 설명할 것이다.

  • 호환되지 않는 코드 삭제
STARTUPINFO와 CREATE_NEW_CONSOLE는 Windows 전용 속성이다.

위 문장을 아래 코드로 변경하면 후에 도커 컨테이너에서 에러를 내뿜지 않게 된다.

    process = subprocess.Popen(cmd, shell=False)

컨테이너 빌드 준비

지금까지 마개조를 진행했다면, 최소한 Synology에서 돌리는데 큰 문제는 발생하지 않을 것이다. 이제부터는 이 파일을 가지고 Synology 컨테이너 매니저에 컨테이너를 빌드해보도록 하자.

  1. 마개조한 파일 업로드

마개조한 파일이 포함된 폴더를 Synology에 업로드하자. 대부분 도커 컨테이너들은 docker 공유폴더를 별도로 만들어 관리하니, 미리docker 공유폴더를 만들어 두자.

나는 docker 공유폴더에 python이라는 폴더를 생성하여 거기 안에 업로드했다.

원하는 경로에 수정한 폴더를 집어넣자.
  1. Dockerfile 생성 및 업로드

메모장을 켜서 아래처럼 입력하자.

# 베이스 이미지로 파이썬 사용
FROM python

# 시스템 패키지 업데이트 및 필수 패키지 설치
RUN apt-get update && apt-get install -y \
    git \
    ffmpeg \
    && apt-get clean

# Streamlink 설치 (PyPI를 통해 설치)
RUN pip install --no-cache-dir streamlink

# 작업 디렉토리 설정
WORKDIR /app

# 호스트의 파일을 컨테이너로 복사
COPY . /app

# run.py 스크립트를 실행하도록 설정
CMD ["python", "run.py"]

파일을 Dockerfile로 저장하고 확장자인 .txt를 수정하여 지우자. 그러면 "Dockerfile"이라는 확장자 없는 파일이 만들어진다.

이 파일을 우리가 업로드 했던 폴더, 즉 run.py파일이 있는 곳에다가 집어넣자.

컨테이너를 빌드하는 방법은 두 가지가 있다. Dockerfile을 ssh에서 직접 빌드하거나, docker-compose를 통해 프로젝트로 빌드하는 방법이 있다. 필자는 docker-compose로 빌드하는 것을 추천한다.

SSH에서 Dockerfile 직접빌드

이제 SSH를 켜주자. SSH 사용법은 여기서 다루지 않겠다.

PuTTY를 기준으로 sudo 권한을 얻은 후, 업로드했던 폴더가 있는 디렉터리로 이동하자. 대부분 cd ../../하면 공유폴더가 있는 곳이 된다. 거기서 업로드한 디렉토리로 이동해라.

Dockerfile이 있으면 된다.

Dockerfile이 있다면 아래의 코드를 입력하자

docker build -t [이미지 이름] .

이걸 입력하고 조금 기다리면 다시 입력창이 뜰 건데, 이미지 빌드는 성공한 것이다.

이제 이걸 실행시켜 주기만 하면 된다.

docker run -d --name [이미지 이름] -v /etc/localtime:/etc/localtime:ro -v /[로컬 경로]:/app [이미지 이름]

여기서 중요하게 봐야할 것이 있는데

-v /[로컬 경로]:/app

바로 이것이다. 여기서 /app은 [매핑 경로]라고 생각하면 된다.

도커는 vm이기 때문에 독립적인 스토리지를 가지고 있다. 독립적인 스토리지와 로컬 스토리지를 매핑시켜 줘야하는데, ":" 기호로 매핑시켜 준다.

[매핑 경로][로컬 경로]에서 시작하게 된다. 이를 통해 도커에서 다운로드 받은 파일은 로컬 스토리지에 그대로 저장이 된다.

아까 소스 코드에서 저장할 파일 경로를 "/app/test/" 이렇게 적었다면 [매핑 경로]도 app으로 설정하면 된다.

docker-compose를 활용한 빌드

이번에는 ssh를 열 필요 없이 시놀로지에서 클릭 몇 번으로 컨테이너를 만들어 보도록 하자.

  1. Container Manager 프로젝트 생성

컨테이너 프로젝트에서 생성 버튼을 누른다.

  1. 프로젝트 생성 설정 입력

프로젝트 이름을 설정하고 경로를 run.py 파일이 존재하는 폴더로 설정한다.

원본은 docker-compose.yml 만들기 로 설정한 후 내용으로 아래와 같이 작성한다.

version: '3.8'

services:
  chzzk_live_recorder:
    image: chzzk_live_recorder:latest
    build:
      context: .
      dockerfile: Dockerfile
    container_name: chzzk_live_recorder
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /volume1/docker/python/cr0814:/app

설정을 완료했으면 자동으로 컨테이너가 생성된다.

결과

테스트 방송을 실시간 녹화하는 로그

내 방송으로 테스트 해봤다. 방송이 시작되고 녹화가 시작되는 로그가 찍힌다.

테스트 방송이 종료된 후 녹화가 끝나는 로그

방송이 끝나면 녹화가 종료되고 인코딩 작업을 시작한다.

녹화가 저장됨

내가 설정한 경로에 잘 저장이 되었다. 방송 환경이 좋지 못하다면 api 통신이 중복해서 응답하기 때문에 2개가 저장될 수 있다. Lite 버전 특성상 무한루프로 api 요청하기 때문에 어쩔수 없는 부분이다.

대부분 긴 영상을 녹화한다면 (2)가 적힌 파일은 대개 짧은 영상이고 나머지는 풀 영상 그대로 저장되니 걱정말기 바란다.

제작자가 만든 프로그램은 계속 업데이트 중이니, 오늘 써먹은 방법이 언젠가는 막힐 수 있다. 최신 버전이 막힌다면 내가 사용한 버전인 0.9 0811 버전을 사용하기 바란다.


09-09 추가

최근들어 제작자가 1.0 버전을 준비 중이라고 한다. web을 통해 gui를 지원할 것이라는 이야기가 있는데, 나는 무척 기대 중이다. 1.0 버전도 시놀로지에서 돌아가도록 시도해 볼 것이고 추후에 글로 작성하겠다.