대략적인 서비스 처리의 순서
영상 소스(OBS Studio) -> RTMP로 실시간 전송 -> [플랫폼에서 수신]->[실시간 트랜스코딩]->[실시간 .m3u8 및 .ts 생성]-> 클라이언트 스트리밍
EC2 포트 열어주기
필요한 패키지 설치
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install nginx
sudo apt install libnginx-mod-rtmp # nginx와 rtmp를 위한 패키지
sudo apt install net-tools # ufw status 확인 시 필요
방화벽 설정
sudo ufw allow 22/tcp # ssh 프로토콜
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp # https 프로토콜을 쓴다면
sudo ufw allow 1935/tcp
sudo ufw allow 8088/tcp
NginX 설정
# sudo vi /etc/nginx/nginx.conf
# RTMP 모듈 설정 시작
rtmp {
# RTMP 서버 설정 시작
server {
# RTMP 포트 번호
listen 1935;
# 데이터 전송 시 4KB 블록 크기
chunk_size 4096;
# RTMP 어플리케이션 설정 시작
application live {
# 라이브 스트리밍 활성화
live on;
# 녹화 비활성화
record off;
# HLS 설정 시작
hls on;
# HLS 저장 경로
hls_path /var/www/html/stream/hls;
# HLS 단편(fragment) 길이
hls_fragment 3s;
# HLS 플레이리스트 길이
hls_playlist_length 5s;
# HLS 정리(삭제) 설정 (옵션으로 주석처리)
#hls_cleanup off;
# RTMP 어플리케이션 설정 종료
}
# RTMP 서버 설정 종료
}
# RTMP 모듈 설정 종료
}
위의 값들 중 추후 성능 및 사용자 환경에 따라 조절을 고려해볼만한 값들
- chunk_size:
- 설명: RTMP 프로토콜에서 사용되는 데이터 전송의 기본 블록 크기를 나타냅니다.
- 조정 고려사항:
- 큰 파일을 다루거나 네트워크 대역폭이 높을수록 큰 값이 유리할 수 있습니다.
- 하지만, 작은 파일이나 네트워크 대역폭이 제한된 경우에는 작은 값으로 조정할 수 있습니다.
- hls_fragment:
- 설명: HLS 스트리밍에서 각 단편(fragment)의 길이를 나타냅니다.
- 조정 고려사항:
- 사용자 경험 및 네트워크 대역폭에 따라 조절될 수 있습니다.
- 작은 값은 빠른 스트리밍 시작을 제공하지만, 네트워크 비용이 증가할 수 있습니다.
- 긴 값은 전체 스트림의 지연을 감소시키지만, 재생 시작이 느려질 수 있습니다.
- hls_playlist_length:
- 설명: HLS 스트리밍에서 플레이리스트의 길이를 나타냅니다.
- 조정 고려사항:
- 스트리밍의 부드러움과 지연 시간에 영향을 미칩니다.
- 작은 값은 더 빠른 플레이리스트 갱신을 의미하지만, 클라이언트 측에서 지연이 발생할 수 있습니다.
- 큰 값은 플레이리스트 갱신이 느리지만, 부드러운 스트리밍을 제공합니다.
코드에 적혀 있지 않지만 나중에 고려해볼 만한 것들
- worker_processes:
- 설명: Nginx가 사용하는 worker 프로세스의 수를 나타냅니다.
- 고려사항: 서버의 코어 수 및 가용 리소스에 따라 조절합니다. 보통 코어 수에 맞춰 설정합니다.
- worker_connections:
- 설명: 각 worker 프로세스가 동시에 처리할 수 있는 연결 수를 나타냅니다.
- 고려사항: 네트워크 연결 수에 따라 조절하며, 고가용성을 위해 높은 값이 필요할 수 있습니다.
- events 블록의 multi_accept:
- 설명: 여러 연결을 동시에 수락할 것인지 여부를 결정합니다.
- 고려사항: 높은 동시 접속을 처리할 때는 on으로 설정하면 유용할 수 있습니다.
- rtmp 블록의 rtmp_auto_push:
- 설명: 자동으로 푸시 모드를 사용할 것인지 여부를 결정합니다.
- 고려사항: 특정 요구사항에 따라 설정하며, 필요에 따라 on 또는 off로 조절합니다.
- rtmp 블록의 rtmp_max_streams:
- 설명: 각 RTMP 어플리케이션에서 동시에 처리할 수 있는 최대 스트림 수를 나타냅니다.
- 고려사항: 서버의 성능 및 사용 패턴에 따라 조절하며, 초과할 경우 연결이 거부될 수 있습니다.
- http 블록의 sendfile:
- 설명: 정적 파일을 전송할 때 sendfile을 사용할지 여부를 결정합니다.
- 고려사항: 정적 파일 서비스를 위해 on으로 설정하면 성능이 향상될 수 있습니다.
- http 블록의 tcp_nodelay 및 tcp_nopush:
- 설명: TCP_NODELAY 및 TCP_NOPUSH 옵션을 사용할지 여부를 결정합니다.
- 고려사항: 네트워크 튜닝을 위해 필요에 따라 설정하며, 일부 경우에는 성능 향상을 가져올 수 있습니다.
#sudo vi /etc/nginx/sites-avaliable/default
server {
listen 8088;
location / {
add_header Cache-Control no-cache;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Expose-Headers' 'Content-Length';
# :8088 의 root 경로를 지정
root /var/www/html/stream/hls;
types {
application/vnd.apple.mpegurl m3u8;
}
}
}
참고사항
Nginx RTMP 모듈을 사용하여 라이브 스트리밍을 설정하면, 기본적으로 H.264(비디오), AAC(오디오) 코덱이 사용된다.
이 둘은 대부분의 브라우저 및 플랫폼에서 지원되는 표준 코덱이기에 일반적으로 문제가 없지만
꼭 다른 특정 코덱을 사용해야겠다면, Nginx RTMP 모듈의 설정에서 'exec' 블록을 사용해 FFmpeg 명령어를 통해 변경 가능하다
#예시
application live {
live on;
exec_push ffmpeg -i rtmp://source_server/source_stream -c:v libx264 -c:a aac -f flv rtmp://localhost/myapp/mylivestream;
}
그리고 만약 화질을 설정하고싶다면
이 또한 FFmpeg 명령어를 통해 변경 가능하다.
-b:v 옵션을 사용하여 비디오 비트레이트를 설정하고, -s 옵션을 사용하여 해상도를 설정하면 된다.
#예시
application live {
live on;
exec_push ffmpeg -i rtmp://source_server/source_stream -c:v libx264 -b:v 1500k -s 1280x720 -c:a aac -f flv rtmp://localhost/myapp/mylivestream;
}
브라우저에서 확인 해보자
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script src="https://vjs.zencdn.net/8.3.0/video.min.js"></script>
<title>Hls Practice</title>
<style>
video {
max-width: 500px;
width: 100%;
max-height: 500px;
height: 100%;
object-fit: fill;
}
</style>
</head>
<body>
<!--
controls : 사용자가 비디오 컨트롤이 가능하게 할 수 있다
playsinline : 전체 화면 방지이다
autoplay : 자동재생이며 , 정책상 음소거 상태에서 가능하다.
-->
<video id="video" controls playsinline autoplay></video>
<script>
/* video Element */
let video = null;
/* 샘플 m3u8 url */
let videoSrc = 'http://ip주소:포트/스트림키.m3u8';
/* initVideo */
const initVideo = () => {
video = document.querySelector('#video')
}
/* DOMContentLoaded 로드를 통해 video Element 담기*/
window.addEventListener("DOMContentLoaded", () => {
initVideo();
})
/* initHls : hls를 초기화 하는 함수 */
const initHls = () => {
if (Hls.isSupported()) {
hls = new Hls({
autoStartLoad: false,
});
hls.loadSource(videoSrc);
hls.attachMedia(video);
hls.startLoad();
}
/* ios/safari 같은 경우에 hls가 built-in 되어있다.*/
else {
video.src = videoSrc;
}
}
/* DOMContentLoaded 로드를 통해 video Element 담기*/
window.addEventListener("DOMContentLoaded", () => {
initVideo();
initHls();
})
</script>
</body>
</html>
보안에 대한 문제
현재 상태는 서버의 주소만 알면 누구나 서버에 접근이 가능해 자원을 잡아먹거나 영상 탈취 가능 등 보안에 문제가 있다
이 문제를 해결하기 위해
Nginx RTMP 모듈에서 사용되는 두 가지 이벤트 핸들러(hook) on_publish 및 on_play를 사용해서 접근에 제한을 둘 예정이다.
on_publish : 클라이언트가 스트림을 퍼블리시(방송 시작)할 때 발생.
on_play : 클라이언트가 스트림을 플레이(시청 시작)할 때 발생
서버단에서 키발급 후 그 키의 정보를 저장하고
application live {
live on;
on_publish http://localhost:8080/check-publish-auth;
}
이렇게 인증 절차를 해볼 생각
'미디어서버(Nginx RTMP)' 카테고리의 다른 글
Nginx.conf의 옵션들 (Nginx RTMP) 및 화질 여러개 송출 (0) | 2024.03.10 |
---|---|
nginx 미디어서버 딜레이 줄이기 (0) | 2024.02.24 |
미디어 서버의 종류 (0) | 2024.01.29 |
미디어 서버를 이해해보자 (0) | 2024.01.29 |
스트리밍 프로토콜(RTSP,RTMP, HLS) (0) | 2024.01.22 |