문제 상황
네이버 부스트캠프에서 그룹프로젝트로 스트리밍 서버를 만들고 있었다. 백엔드인 나와 다른 팀원 1명은 페어 프로그래밍을 하면서 문제를 맞닥뜨렸다.
문제: OBS를 사용해 RTMP 수신 서버로 스트리밍 데이터를 보내고 다시 인코딩 서버를 거쳐 Object Storage에 m3u8, ts 파일을 저장했는데 화면이 없이 오디오만 스트리밍 된다.
해결 과정
hls 가 애플에서 만든거니까 인코딩할 때 Apple H.264로 바꿔서 하면 되지 않을까 해서 바꿔서 해봤더니 잘 됐다. 그래서 윈도우에서는 AMD h.264로 해봤는데 안됐다. 왜 윈도우에서는 안되는지 구글링을 해도 뭐가 원인인지 감이 안와서 GPT 한테 물어보았다. GPT 가 알려준 답변을 보며 백엔드 팀원과 함께 논의를 통해 먼저 우리가 사용하고 있는 node-media-server 모듈에서 비디오 포맷을 받는 설정을 어떻게 하는지 찾아 보았다.
OBS 비디오 인코더가 맥북에서는 Apple H.264, 윈도우에서는 NVIDIA NVENC H.264, AMD H.264가 있었는데
맥북에서 비디오 인코더를 Apple H.264로 설정하면 화면을 포함해 정상적으로 스트리밍이 됐다. 하지만 윈도우는 모든 인코더가 동일하게 오디오만 나왔다.
RTMP 수신 서버는 node-media-server 라이브러리를 사용하는데 여기서 아래 명령어로 다음 서버에 relay한다.
ffmpeg -re -i [INPUT-URL] -c copy -f flv [인코딩-서버-URL]
이 명령어는 비디오는 H264, 오디오는 AAC 포맷이어야 RTMP 요청이 정상적으로 동작한다.
ffmpeg -re -i [INPUT-URL] -c:v libx264 -preset veryfast -tune zerolatency -c:a aac -ar 44100 -f flv [인코딩-서버-URL]
스트리밍 서버에 경우 어떠한 포맷으로 요청이 오더라도 정상 작동해야 되므로 위처럼 포맷을 수정하도록 명령어를 바꿀 필요가 있었다.
하지만 node-media-server 내부에서 ffmpeg 명령을 호출하는데 argv를 설정하는 기능은 제공하지 않았다.
그래서 node-media-server의 github의 이슈에는
relay할 때 ffmpeg argv를 동적으로 설정할 수 있는 기능을 추가하자는 PR도 있었다. 그런데 이 PR이 merge가 안된 상태였다. 그래서 이 pr을 참고 해서 하드코딩해서 수정본을 만들었다.
https://github.com/illuspas/Node-Media-Server/pull/559/files
Add support to customize ffmpeg output options in relay and fission t… by realaboo · Pull Request #559 · illuspas/Node-Media
Currently FFmpeg output options are hardcoded to -c copy for relay tasks and libx264 for fission tasks. This PR add support to customize FFmpeg output options for these tasks. Thus FFmpeg filters, ...
github.com
ffmpeg 명령어를 호출하는 기존의 node_modules/node-media-server/src/node_relay_session.js
파일을 복사해서, 그 안의 코드를 수정한 수정본 파일을 만들었다.
그리고 이 수정본을 적용하는 코드를 Dockerfile에 추가해 ffmpeg의 argv를 수정했다.
전
후
RUN mv ./node_relay_session.js ./node_modules/node-media-server/src/node_relay_session.js
느낀 점
페어프로그래밍을 하면서 서로 왜 문제가 났는지, 어떻게 해결해야 하는지 같이 논의를 하니 더 빠르게 오류를 해결 할 수 있었다. 처음으로 node module의 코드를 수정해서 오류를 해결해 봤는데, 이렇게도 오류를 해결 할 수 있다는 것을 배웠다. 이전에는 node module이 완벽한 코드가 있다고만 생각했는데, 그게 아니라는 것을 배울 수 있었다.