fmp4 포맷의 데이터는 프레그먼트 데이터를 도중의 아무 데이터를 보내더라도 그 시점으로부터 재생을 할 수 있다는 특징을 가지고 있다. 그러므로, 언제 요청이 들어오더라도 현재 시점부터 재생을 시작해야 하는 라이브 영상 재생에 적합한 포맷이라고 할 수 있다. 그러나, 재생을 하기 위해서는 데이터 프레그먼트가 들어오기 전에 항상 초기화 프레그먼트라는 것을 먼저 다운로드해서 초기화시켜줘야 한다. 아마도 파일 형식, 해상도, 오디오 코덱 등의 정보가 들어있지 않을까 한다. 이 정보를 통해서 재생하는 쪽에서도 어a떤 코덱을 써야 할지 어떤 방식으로 미디어 데이터를 디먹싱할 수 있는지 등을 결정할 수 있을 것이다.

ffmpeg을 통해서 스트림을 파이프로 수신하게 되면 이 데이터 역시 프레그먼트 단위로 보내긴 할 것이다. 그러나 파이프라인 수신 시에 내부적인 버퍼링 등의 작업을 통해 합쳐질 수도 있는 것이다. 재생을 위해서는 이 프레그먼트 단위로 분리해서 전송하는 기능이 필요하며, 또한 최초에는 초기화 프레그먼트를 보내도록 하는 기능도 필요하다. 이 기능을 지원하는 모듈이 있는데 mp4frag라는 모듈이다.

https://www.npmjs.com/package/mp4frag

mp4frag이미지 썸네일 삭제

mp4frag

A parser that reads piped data from ffmpeg containing a fragmented mp4 and splits it into an initialization segment and media segments. Designed for streaming live video relayed from cctv cameras.. Latest version: 0.7.0, last published: a year ago. Start using mp4frag in your project by running `npm…

www.npmjs.com

우선 mp4frag 모듈을 설치해야 한다.

1
npm i mp4frag

모듈을 가져와서 이 모듈을 사용하기 위한 인스턴스를 하나 생성해야 한다.

1
2
const Mp4Frag = require("mp4frag");
const mp4frag = new Mp4Frag();

이 인스턴스에 fmp4 포맷의 스트림을 밀어 넣어주면 된다. mp4frag로부터 segment라는 이벤트를 통해 재생을 바로 할 수 있는 조각을 얻어낼 수 있게 되며, mp4frag.initialization을 접근하면 초기화 프레그먼트를 얻을 수 있다.

우선, ffmpeg으로부터 나오는 스트림을 mp4frag에 밀어 넣는다. segment 이벤트가 발생하는지를 확인할 코드를 넣어 보자.

1
2
3
4
ffmpeg.stdio[1].pipe(mp4frag);
mp4frag.on("segment", (data) => {
console.log(data);
});

이전 코드에서 스트림이 발생하는지를 확인해 보기 위해 표준 출력으로 밀어 넣는 기능을 제거한다. 대신 mp4frag.initialization을 확인해 본다.

1
2
3
4
5
io.on("connection", (socket) => {
console.log("connection");
//ffmpeg.stdio[1].pipe(process.stdout);
console.log("initialization:", mp4frag.initialization);
});

여기까지 작업한 것을 실행해 보자.

segment 이벤트가 발생할 때 콜백으로 들어오는 data 인자는 다음과 같은 형식이다.

1
2
3
4
5
6
7
data: {
segment: <Buffer 00 00 01 28 6d 6f 6f 66 00 00 00 10 6d 66 68 64 00 00 00 00 00 00 00 05 00 00 01 10 74 72 61 66 00 00 00 1c 74 66 68 64 00 02 00 38 00 00 00 01 00 00 ... 600959 more bytes>,
sequence: 4,
duration: 1,
timestamp: 1715589705022,
keyframe: true
}

여기에서 가장 중요한 부분은 바로 segment라는 필드이다. 이 데이터가 영상의 재생에 사용할 수 있는 스트림이다.

initialization 값은 다음과 같이 나온다.

1
initialization: <Buffer 00 00 00 1c 66 74 79 70 69 73 6f 35 00 00 02 00 69 73 6f 35 69 73 6f 36 6d 70 34 31 00 00 04 ba 6d 6f 6f 76 00 00 00 6c 6d 76 68 64 00 00 00 00 00 00 ... 1188 more bytes>

둘 다 Buffer 타입으로 미디어나 미디어를 설명하는 메타데이터가 들어있을 것임을 짐작할 수 있다. 재생에 필요한 데이터를 획득하는 방법을 알았으니 이젠 전송해서 재생을 해주면 될 것 같다. 작업한 내용은 다음 깃헙 저장소에 업데이트한다.

https://github.com/moonyl/mse-remind/tree/v0.3.0

GitHub - moonyl/mse-remind at v0.3.0이미지 썸네일 삭제

GitHub - moonyl/mse-remind at v0.3.0

Contribute to moonyl/mse-remind development by creating an account on GitHub.

github.com