nginx rtmp를 이용해서 실시간 스트리밍 구현 예제(HLS 프로토콜 추가)

nginx rtmp를 이용해서 실시간 스트리밍 구현 예제(HLS 프로토콜 추가)

 

지난 시간에 이어서 nginx의 rtmp 모듈을 이용해서 실제로 유저간 방송을 송출하고, 실시간으로 방송을 수신하는 예제를 구현해 보겠습니다.

 

실시간 스트리밍에 관련한 기본 개념들은 이 포스팅(NGINX에서 RTMP와 FFmpeg 라이브러리를 이용한 HLS 송신 예제)을 참고해주세요. 전부 읽는데 15분 정도 걸립니다.

 

준비사항은 nginx 서버와 nginx rtmp 모듈이 설치되어 있고, 설정이 되어 있어야 합니다.

 

이번에 구현할 시나리오는 아래와 같습니다.

 

시나리오

[1] 시나리오 rtmp -> hls

1-1.유저 A가 OBS 스튜디오를 이용해서 실시간 방송(rtmp 프로토콜 이용)

1-2.nginx-rtmp 서버가 받아서 hls 로 트랜스먹싱 처리 해서 http 프로토콜을 이용해서도 실시간 스트리밍을 수신할 수 있게 처리

1-3.유저 B가 HLS 플레이어를 지원하는 브라우저에서 유저 A가 방송하는 영상을 실시간으로 시청

 

[2] 시나리오 rtmp - rtmp

1-1.유저 A가 OBS 스튜디오를 이용해서 실시간 방송(rtmp 프로토콜 이용)

1-2.nginx-rtmp 서버가 받아서 그대로 rtmp 프로토콜로 송신

1-3.유저 B가 rtmp 실시간 스트리밍을 지원하는 플레이어에서 유저A가 송출하는 방송 시청

 

먼저 nginx 설정파일 부터 확인하겠습니다.

 

설정파일

/etc/nginx/nginx.conf 

nginx 설정관련해서 여러 설정 값들이 존재하지만 아래 주석으로 #  HLS 형식으로 변환 # RTMP 전용 주석 부분만 확인해 주세요.

#  HLS 형식으로 변환 부분은 시나리오 1에 해당하는 설정 부분이고,  # RTMP 전용 주석 부분은 시나리오 2에 해당하는 설정 부분입니다.

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
	# multi_accept on;
}

# 영상을 미디어 서버로 보낼때 사용하는 프로토콜
# nginx rtmp 설정
rtmp {
        server {
		# rtmp 포트 번호
                listen 1935;
		listen [::]:1935 ipv6only=on; # 어디에서 오던 받아주도록 설정		
		
		# rtmp 가 4k 블록으로 데이터 전송
                chunk_size 4096;


		#  HLS 형식으로 변환 (트랜스먹싱 혹은 패킷타이징이라고 함)		
                application live {
                        live on;
                        record off;
               		
			#HLS
			hls on;
                        hls_path /var/www/html/stream/hls;
                        hls_fragment 3;
                        hls_playlist_length 60;

                        dash on;
                        dash_path /var/www/html/stream/dash;
		 }

		# RTMP 전용
		# onlyRtmp 
                application live_rtmp {
                        live on;
                        record off;
	    	 }		


		# 테스트 - TEST
           	 application live2 {
                    live on;
                    record off;
                    exec ffmpeg -i rtmp://localhost/live2/$name -threads 1 -c:v libx264 -profile:v baseline -b:v 350K -s 640x360 -f flv -c:a aac -ac 1 -strict -2 -b:a 56k rtmp://localhost/live360p/$name;
            	}
	    
 	   	# 저장하기 - TEST
            	application live_save {
                    live on;
                    record off;
			
		    exec ffmpeg -i rtmp://localhost/$app/$name -c copy -f mp4 /var/www/html/stream/savefile/$name.mp4;
	
		}
        }
}


http {

	# Basic Settings

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	# SSL Settings

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	# Logging Settings

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	# Gzip Settings

	gzip on;


	# Virtual Host Configs

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

 

/etc/nginx/sites-available/default

시나리오 1을 위해서 추가 설정이 필요한데 내용은 아래와 같습니다.

8088 포트를 통해 스트리밍을 요청할 수 있습니다. 따라서 8088 포트를 열어놓아야 합니다.

그리고 rtmp 실시간 스트리밍 데이터는 /var/www/html/stream 이 경로의 hls 폴더에 ts 파일과 m3u8 파일로 나뉘어서 저장이 됩니다. 

#미디어 서버 주석 부분을 참고해주세요.

# 미디어 서버
# rmtp - hls 포트
server {
    listen 8088 ssl;

    ssl_certificate /etc/letsencrypt/live/나의 도메인/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/나의 도메인/privkey.pem;


     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;

        types {
            application/vnd.apple.mpegurl m3u8;
        }
       
	# alias /tmp/hls/;
      }
}



# 80번 포트로 들어오면 443 포트로 redirect
server {

	listen 80 default_server;
	listen [::]:80 default_server;
	server_name 나의 도메인;

    if ($host = 나의 도메인) {
        return 301 https://$host$request_uri;
    } 
}



# 443 포트로 들어오면 nodejs 3000 포트로 redirect
server {
    # 아마존 서버 경우 앞에 www. 붙여야됨.
    server_name 나의 도메인;

    listen [::]:443 ssl ipv6only=on; 
    listen 443 ssl;

    ssl_certificate /etc/letsencrypt/live/나의 도메인/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/나의 도메인/privkey.pem; 

	location / {
		proxy_pass http://127.0.0.1:3000;
		#try_files $uri $uri/ =404;
	}
}

 

실시간 스트리밍 테스트

시나리오 1 번 테스트

먼저 시나리오 1번을 테스트 해보겠습니다.

obs를 이용해서 실시간 스트리밍을 내보냅니다.

obs 스튜디오에 관해서는 이곳을 참고해 주세요.

obs 스튜디오를 열어서 방송 설정을 아래와 같이 해줍니다.

유저가 OBS 스튜디오를 이용해서 rtmp 프로토콜을 이용해서 방송을 스트리밍 하기 위해 설정합니다.

 

실시간으로 송출되는 유저 A의 pc 화면

obs 스튜디오에서 실시간으로 방송하는 모습

 

서버에는 실시간으로 ts 파일과 m3u8 파일이 생성됩니다.

 

유저 B는 HLS 플레어를 지원하는 브라우저에서 실시간으로 화면을 볼 수 있습니다.

실시간 방송 확인 성공

 

시나리오 2 번 테스트

이어서 시나리오 2번을 테스트 해보겠습니다.

유저A가 방송을 송출하기 위해서 OBS 스튜디오의 설정값을 지정합니다. 서버의 주소와 스트림키가 시나리오 1번과 다른것을 확인해주세요.

 

유저 A가 실시간으로 자신의 컴퓨터 화면을 위에서 설정한 주소로 송출하고 있습니다.

 

유저 B는 팟플레이어를 다운받아서 열기 -> 주소로 열기 에 들어가서 재생하려는 인터넷 주소를 입력합니다. 

현재 유저 A가 설정한 주소여야겠죠?

 

위에서 주소를 잘 입력해서 현재 유저A가 OBS 스튜디오에서 rtmp 프로토콜로 방송하는 스트리밍을 유저B는 실시간으로 확인할 수 있습니다.

실시간 rtmp 프로토콜로 방송하는 스트리밍 수신 성공

 

 

참고한 사이트

https://www.hostwinds.kr/tutorials/live-streaming-from-a-vps-with-nginx-rtmp

https://blog.bumnyeong.com/2020/01/nginx.html

https://3jini.tistory.com/247