1. WebRTC에서 Media Server로 갈아탄 이유
1) WebRTC
WebRTC는 P2P 방식을 쓴다.
P2P란 중간 서버를 거치지 않고 클라이언트 끼리 알아서 소통을 하는 방식.. 인데,
내가 하려는건 단순 영통이 아니라 대규모 라이브스트리밍이다.
라방을 하는 한 사람이 수천~수만명의 시청자와 동시에 연결되려면 그 모든 연결을 관리하기에는 쉽지 않을거라 판단함
2) Media Server
Kurento, OpenVidu, Node-Media-Server 등이 있는데, 여기서 제일 구현하기 간단하고 라이브스트리밍을 구현하기도 적합한 노드 미디어 서버를 사용하기로 함..!!
+) 라이브스트리밍을 서버에 보낼땐 RTMP 프로토콜을 사용, 서버에서 시청자에게 데이터를 전송할때는 HLS 프로토콜을 사용해야하는데, RTMP를 HLS로 변환하는 과정을 노드 미디어 서버에서 처리가 가능하다고 함
2. RTMP란?
- 비디오, 오디오 등을 인터넷상에서 실시간으로 스트리밍 데이터를 전송해서 불특정 다수들이 받아볼 수 있도록 하는 어도비 독점 프로토콜
- 라이브 스트리밍을 하는 쪽에서 RTMP 규격을 거쳐 서버로 데이터를 전송 후, 서버에서 다른 클라이언트로 HLS 등으로 전송됨
- 아프리카TV, 트위치, 유튜브 등...
- 작동 방법
- OBS에서 미디어 캡쳐와 인코딩 처리
- RTMP 프로토콜 > 네트워크를 통해 RTMP 서버로 패킷들을 전송
- 서버는 패킷을 실시간으로 시청자에게 보냄
- 웹브라우저는 RTMP 프로토콜을 지원하지 않기 때문에, HLS를 이용하여 비디오를 재생해야 함
- Node Media Server > RTMP, HLS 모두 지원, but Node.js 기반으로 구축된거라 Nest에서 적용이 똑같이 잘 될지는 의문임.. 어떻게든 되겠지 뭐....
3. Node Media Server를 이용하여 RTMP 서버 만들기
1) 패키지 설치
nest.js 초기셋팅 없이 index.js 한 파일에서 다룰 것이기 때문에 node media server만 설치하면 됨
mkdir nms
cd nms
npm init -y
npm install node-media-server
vi index.js
2) index.js 파일 생성
일단 기본 구조는 다음과 같다.
const NodeMediaServer = require ( "node-media-server" );
// Node Media Server에는 구성 매개변수가 필요합니다.
const config = {};
const nms = new NodeMediaServer (config);
// run 메서드를 사용하여 미디어 서버를 시작합니다.
nms.run ( );
config의 구성요소는 다음과 같다.
- http : hls를 사용하여 클라이언트에 라이브스트림을 제공하기 때문에, 서버에서 http를 활성화해야함
- port : HTTP 서버가 HLS 스트리밍을 수신하는 포트번호
- allow_origin : 서버 리소스에 액세스할 수 있는 출처 지정 > CORS 제어, * 는 모든 출처의 요청 허용
- mediaroot : 서버가 미디어 파일을 찾을 디렉토리 경로
- rtmp : 스트리머는 rtmp 프로토콜을 통해 패킷을 서버로 전송함
- port : RTMP 서버의 포트 번호, 기본 1935
- chunk_size : RTMP 스트리밍의 청크 크기 byte 단위, 미디어파일은 chunk_size 에 따라 쪼개짐
- gop_cache : GOP(Group of Pictures, 영상 프레임의 집합?) 캐시를 사용할지 여부, 사용시 RTMP 스트리밍 효율은 좋지만 메모리 사용량도 증가함
- ping : ping 메시지를 보내는 시간 간격, RTMP 서버와 연결된 클라이언트간의 모니터링 용
- ping_timeout : ping 메시지의 시간초과 기간
- trans : 변환 작업을 여기서 선언함. 인코딩 된 미디어 컨텐츠를 MPEG-2 transport stream 파일로 변환
- ffmpeg : ffmpeg 실행 파일 경로 (Docker를 사용하지 않을 경우 ffmpeg를 다운받고 실행파일 경로를 적어야함)
- tasks : 애플리케이션의 다양한 구성 지정
- app : 애플리케이션 이름
- hls : 이 애플리케이션에 대해 HLS 활성화 여부
- hlsFlags
- hls_time=2 : 각 hls segment의 지속시간을 초 단위로 지정, segment 의 지속시간이 2초라는 뜻
- hls_list_size=3 : 주어진 시간에 hls 플레이리스트에 나열된 segment 의 수, hls 플레이리스트에 마지막 3개의 segment 에 대한 참조가 포함, 그 외에는 삭제
- hls_flags=delete_segments : delete_segments 서버에 더이상 플레이리스트에서 참조되지 않는 HLS segment를 삭제, 즉 더이상 재생에 필요하지 않은 segment를 제거하여 디스크 공간 관리
- hlsKeep : 스트림 종료 후 HLS 파일을 유지할지 여부
- hlsFlags
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
mediaroot: './media',
allow_origin: '*'
},
trans: {
ffmpeg: '/Users/.../ffmpeg-7.0.1-essentials_build/ffmpeg-7.0.1-essentials_build/bin/ffmpeg.exe',
tasks: [
{
app: 'live',
hls: true,
hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]',
hlsKeep: true, // to prevent hls file delete after end the stream
}
]
},
};
4. 라이브 스트리밍 테스트
설정 > 방송 > 사용자 지정
- 서버 : 기본포트인 1935 사용 > 포트번호 생략 가능, config에서 지정한 애플리케이션 이름을 끝에 사용
- 스트림 키 : 임의 지정
메인에서 방송 시작
터미널창에 로그 & media 폴더에 index.ts 파일 생성과 삭제 반복되는것 확인
이제 영상을 확인해보자
VLC 미디어플레이어 설치 > 미디어 > 네트워크 스트림 열기 > url 붙여넣기
rtmp://localhost/live/(임의 지정한 이름)
(화면은 내가 가려놨음)
딜레이가 상당하지만(^^...) 되긴 된다...
이제 HLS로도 확인해보자.
https://livepush.io/hls-player/index.html
HLS Player - Free M3U8,DASH Player - Livepush
Livepush.io is a phenomenal platform that has helped me as a content creator to go beyond in every category. Not only does it help my audience watch my content on any platfrom, it also provides me with the crucial insights to help me improve. Sneko Gebiko
livepush.io
여기에 다음을 복붙
http://localhost:8000/live/(임의 지정한 이름)/index.m3u8
확인 완료
딜레이는 나중에 생각하쟈...
'TIL' 카테고리의 다른 글
TIL 240802 - unsigned 속성 / foreign key 에러 (0) | 2024.08.02 |
---|---|
TIL 240801 - 로드밸런싱 (0) | 2024.08.01 |
TIL 240729 - Nest.js Socket 실시간 채팅 (0) | 2024.07.29 |
TIL 240726 - typeorm / scheduler를 이용해서 자동으로 데이터 삭제하기 (0) | 2024.07.26 |
TIL 240725 - 에러 처리 (Referencing column ... in foreign key constraint ... are incompatible.) (0) | 2024.07.25 |