pipe 출력을 가로채기
앞선 글에서 ffmpeg을 이용해서 fm4 형식의 스트림을 pipe:1을 통해 획득할 수 있게 되었다. 그렇다면 이것을 node.js에서 실제로 스트림으로 가로채려면 어떻게 해야 할까.
node.js에서는 child_process 모듈에서 프로세스를 처리하는 기능들을 제공하고 있으며, 그중에 spawn이라는 함수를 이용하면, 이 작업을 할 수 있다. spawn 함수는 자식 프로세스를 생성하고 실행하는 데 사용된다. 자식 프로세스는 별도의 프로세스로 실행되므로 부모 프로세스와 독립적으로 작동한다. 매개 변수는 주로 3개를 이용하게 되는데, 다음과 같다.
- command: 실행할 명령어 또는 스크립트 경로
- args (optional): 명령어에 전달할 인수 배열
- options (optional): 자식 프로세스 생성 옵션 객체
command와 args는 직관적으로 파악할 수 있고, options는 여러 가지를 설정할 수 있는데, 여기에서 관심 있는 옵션은 stdio라는 옵션이다. 배열 형태로 설정하게 되는데, stdin, stdout, stderr 을 순서대로 지정하면 된다. 표준 입출력은 당연히 실행하고자 하는 자식 프로세스의 것을 가리킨다. 자식 프로세스의 표준 입출력을 부모 프로세스의 것과 연결시키려면 inherit 을 설정하면 되고, 특정 스트림으로 연결하고자 하면 pipe로 설정하면 된다. 앞선 ffmpeg 명령으로 결괏값을 얻을 때, 표준 입력은 필요 없고, 표준 출력은 스트림으로 얻어야 하고, 표준 에러는 부모의 표준 에러에 연결해서 표시하도록 하면 된다. 그러므로 다음과 같이 spawn을 호출해 주면 된다.
1 | const ffmpeg = spawn( |
프로세스가 종료되거나 에러가 발생했을 때를 검출하기 위해서 이벤트 핸들러를 추가해 준다.
1 | ffmpeg.on("error", (error) => { |
클라이언트가 접속했을 때 ffmpeg에 파이프를 연결하고 데이터가 넘어오는지 확인해 보자.
1 | io.on("connection", (socket) => { |
ffmpeg 자식 프로세스의 표준 출력을 현재 프로세스의 표준 출력으로 연결했다. npm run dev로 앱을 실행하고, 웹 브라우저에서 http://localhost:3000으로 접속해 보자.
명령을 실행한 터미널에 이전에 명령으로 실행했을 때와 유사하게 이상한 문자들이 등장하는 것을 볼 수 있다. 이 데이터를 웹소켓을 통해 웹브라우저에서 렌더링 할 수 있도록 추가 작업을 해주면 재생 기능을 작성할 수 있게 된다.
Big Buck Bunny라는 소스 영상은 10분가량 되는 영상인데, 실제로 앱을 실행했을 때 금방 종료된다는 것을 확인할 수 있다. 이것은 ffmpeg은 재생하는 것이 아니라 변환하는 툴이기 때문에 소스를 가능한 한 바로 처리하기 때문이다. 실제 속도대로 소스 영상을 입력되도록 하려면 -re라는 옵션을 -i 옵션 이전에 넣어주면 된다. read rate를 1로 설정하는 것으로, 영상의 재생 속도대로 소스가 입력되는 효과를 얻을 수 있다.
ffmpeg에서 발생하는 로그를 좀 더 세밀히 볼 수 있도록 log level도 설정해서 사용하도록 하자. dubug 레벨까지 확인할 수 있도록 -loglevel debug를 추가로 넣어준다.
1 | const ffmpeg = spawn( |
지금까지의 변경 사항은 깃헙 저장소에 반영했다.
https://github.com/moonyl/mse-remind/tree/v0.2.0
이미지 썸네일 삭제
GitHub - moonyl/mse-remind at v0.2.0
Contribute to moonyl/mse-remind development by creating an account on GitHub.
github.com