반응형
1. 브라우저 보안 정책상 자동 재생이 불가하나 그래도 해야겠다면 mute로 실행되어야 한다.
2. hls.js로 스트림 서버 접속해서 영상을 받아오면 된다.

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Live Streams</title>
</head>
<body>
  <video id="live-stream" width="640" height="360" controls autoplay></video>
  <script>
    var video = document.getElementById('live-stream');
   
    if (Hls.isSupported()) {
        var hls = new Hls({
            lowLatencyMode: true,
            liveSyncDurationCount: 1,
            liveMaxLatencyDurationCount: 3,
            liveDurationInfinity: true,
            highBufferWatchdogPeriod: 1,
            nudgeMaxRetry: 5,
            nudgeOffset: 0.1,
            maxFragLookUpTolerance: 0.1,
            startFragPrefetch: true
        });


      hls.loadSource(videoSrc);
      hls.attachMedia(video);
      hls.on(Hls.Events.MANIFEST_PARSED, function() {
        hls.startLoad(-1);  // 가장 최근 세그먼트부터 로드
        video.play();
      });

      hls.on(Hls.Events.ERROR, function(event, data) {
        console.log('HLS error:', data);
        if (data.fatal) {
          hls.destroy();
          setTimeout(() => {
            hls.loadSource(videoSrc);
            hls.attachMedia(video);
          }, 1000);
        }
      });
    }
    else if (video.canPlayType('application/vnd.apple.mpegurl')) {
        video.src = videoSrc;

        video.addEventListener('loadedmetadata', function() {
            if (video.duration > 15) {
                video.currentTime = video.duration - 1;  // 가장 최근 시점으로 이동
            }

            video.play();
        });
    }
  </script>
</body>
</html>

OBS Studio의 설정, node.js 서버설정, 클라이언트에서도 최근 시점으로 이동시키는 설정 등 
3위일체가 되었다면 3초는 아니더라도 5초~8초 사이의 딜레이정도만 존재하는 훌륭한 스트리밍 서비스가 가능하다.
다만 아직 못해본건 서버사양과 대역폭 등에 대한 최대 지원 정도는 테스트 해봐야 함.
경우에 따라선 nginx로 분산처리도 고려 대상임.

* 쿠키 *
만약 youtube의 실시간 채널 라이브 방송을 진행하고 이를 웹브라우저에서 보고 싶다면 아래처럼 iframe을 이용하면 확인할 수 있다.
youtube는 3초 정도의 딜레이가 존재한다.
구글이니까

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Live Streams</title>
</head>
<body>
  <iframe id="live-stream" width="640" height="360" src="https://www.youtube.com/embed/******qSuVkrE?autoplay=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</body>
</html>
반응형
Posted by Hippalus
,

반응형

다른거 다 필요 없다.

방송 송출 서버 주소 설정하고 방송하면 된다.
설정을 해야 하니 제어 > 설정 눌러보면 팝업윈도우가 새로 뜨는데
좌측 메뉴에서 방송 누르고 서비스는 사용자 지정, 서버는 프로토콜을 rtmp로 설정 후 내 node.js 서버가 존재하는 ip, 도메인을 입력 후 그 하위 디렉토리까지 입력해준다.
일전에 nginx 설정할 때 location /live 로 입력했던것 기억하는가?
그 live가 이 live다.
스트림 키는 유저별로 생성해주는 키로 마찬가지로 일전에 /node/stream/media/live/스트림키 어쩌구저쩌구 에 ts파일과 m3u8파일이 생긴다고 말했다.
그때 사용되는 폴더가 이 스트림키로 생성된다.

여기까지만 해도 일단 방송 출력은 될 것이다.
하지만 가장 중요한건 딜레이 줄이기 위한 설정이 남아있다.
이것 몰라서 8시간 헤맸다.

제어 > 설정 눌러보면 팝업윈도우가 새로 뜨는데
여기서 좌측 메뉴들 중 출력 선택 > 고급 선택 > 비디오 인코더 x264, 키프레임 간격 2s, COU 사용량 사전 설정(ultrafast)
이정도만 손봐주면 된다.
이거 안 해주면 15초 25초씩 딜레이 걸린다.
참고로 유튜브라이브는 3초고 rtmp는 5초~8초가 최대 한계다.

만약 웹캠 없이 스마트폰으로 방송을 해야 한다면 iVCam이란 프로그램을 설치하기 바란다.
중공산 프로그램 같긴한데.. 좀 찝찝하다만 동작은 잘 된다.
내 폰은 iPhone인데 PC와 폰 모두 동일한 Wifi로 연결해야만 영상 전송이 가능하다.
따라서 그냥 케이블로 연결했다.
이것도 처음엔 잘 안됐는데 어찌저찌하다보니 되더라.. 그리고 가끔씩 끊어지더라
왜 끊어지는진 모르겠다. 연결 끊김 연결 반복되기도 하더란.. 그래도 뭐 잘은 되니

다 연결해서 화면 뜨고 방송 시작 누르면 방송 된다.

live폴더 아래에 스트림키 폴더에 보면 이렇게 영상 파일들이 실시간으로 생성되는걸 확인할 수 있다.

매번 ls로 확인하기 귀찮으면
watch -n 1 "ls -lR /node/stream/media/live"
이렇게 해두면 알아서 파일이 실시간 확인 가능하다.

다음엔 웹브라우저로 송출받은 영상을 확인해 보겠다.

반응형
Posted by Hippalus
,

반응형

1. node-media-server (nms) 모듈 설치 : npm install node-media-server
2. nms 기본 포트는 1935 사용
3. 앞서 nginx에서 설정했던 7999 포트로 클라이언트 웹브라우저에서 요청시 실시간 영상 제공
4. media파일 경로는 /node/stream/media
    스트림키를 부여 받고 방송을 할 경우 저 media 폴더 하위에 스트림키 폴더가 생성되고 그 안에 ts, m3u8 파일 생성됨
5. 방송 송출자와 시청자의 시간차를 줄이기 위해 hls_time을 2로 설정함. 숫자가 낮을수록 차가 줄어들지만 부하발생

const NodeMediaServer = require('node-media-server');

const config = {
  rtmp: {
    port: 1935,
    chunk_size: 60000,
    gop_cache: false,
    ping: 30,
    ping_timeout: 60
  },
  http: {
    port: 7999,
    allow_origin: '*',
    cors: {
        enable: true,
        origin: '*'
    },
    mediaroot: '/node/stream/media',
    webroot: '/node/stream/www',
  },
  trans: {
    ffmpeg: '/usr/local/bin/ffmpeg', // 여기에 올바른 ffmpeg 경로를 설정합니다.
    tasks: [
      {
        app: 'live',
        hls: true,
        hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]',
        hlsKeep: true, // 스트림 종료 후 hls 파일 삭제 방지
        dash: true,
        dashFlags: '[f=dash:window_size=3:extra_window_size=5]',
        dashKeep: true // 스트림 종료 후 dash 파일 삭제 방지
      }
    ]
  },

  logType: 3 // Debug 레벨 설정
};

const nms = new NodeMediaServer(config);
nms.run();
반응형
Posted by Hippalus
,

반응형

[주요 설정]
1. 8000포트를 사용하여 SSL로 live 클라이언트 웹 브라우저에서 접속
2. 서버의 스트리밍 파일(m3u8, ts등)이 생성되는 곳은 /node/stream/media/live 폴더
3. 빌어X을 CORS는 제낌
4. node.js로 만든 스트리밍 서버에선 클라이언트 브라우저의 요청시 7999포트를 이용해서 hls로 리턴해줄 예정

server {
    listen 8000 ssl;
    server_name dev.*****.co.kr;

    ssl_certificate     /usr/local/nginx/conf/cert/2024/dev_*****_co_kr_NginX_cert.pem;
    ssl_certificate_key /usr/local/nginx/conf/cert/2024/dev_*****_co_kr_NginX_key.pem;
    access_log /usr/local/nginx/logs/dev.*****.co.kr_access_log;
    error_log /usr/local/nginx/logs/dev.*****.co.kr_error_log;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers ******************************************************************************;
    ssl_prefer_server_ciphers on;

    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;

    location /live {
        alias /node/stream/media/live;
        proxy_pass http://127.0.0.1:7999;
        proxy_buffering off;
        proxy_request_buffering off;

        proxy_cache off;

        proxy_read_timeout 10s;
        proxy_send_timeout 10s;
        send_timeout 10s;

        proxy_http_version 1.1;
        proxy_connect_timeout 75s;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        add_header Cache-Control no-cache;

        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }
    }


    location /hls {
        # Disable cache
        add_header Cache-Control no-cache;

        # CORS setup
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length';

        # allow CORS preflight requests
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }
        
        # Serve HLS fragments
        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }
        
        root /tmp;
        add_header Cache-Control no-cache;
    }
}

다음은 node.js로 스트리밍 서버를 만들어보겠다.
서버는 환경설정보다 쉽다.

반응형
Posted by Hippalus
,

반응형

너무 정신 없이 이것 저것 검색해가며 설치하다 보니 잡탕이지만 나름 정리해보자면
nginx를 이용해 스트리밍 방송을 하려면 nginx에 rtmp모듈을 설치하여 컴파일하여야 하고
nms를 이용해 실시간 방송을 하려면 ffmpeg도 설치해야 한다.
현재 실행 권한은 su 권한이다.

먼저 nginx에 rtmp모듈을 설치 및 컴파일을 진행한다.
아래 과정은 Nginx를 커스터마이징하여 필요한 기능을 추가하고, 소스 코드를 컴파일하여 시스템에 설치하는 과정으로 각각의 단계는 다음과 같은 목적을 가지고 있다.

Nginx 소스 코드 다운로드 및 해제: Nginx 소스 코드를 다운로드하고 압축을 해제하여 빌드 준비
RTMP 모듈 다운로드: Nginx에 RTMP 스트리밍 기능을 추가하기 위해 RTMP 모듈 소스 코드를 다운로드
필수 라이브러리 설치: Nginx 빌드에 필요한 PCRE, zlib, OpenSSL 라이브러리와 개발 파일을 설치
configure 실행: 시스템 환경에 맞게 Nginx 빌드 설정을 준비하고, RTMP 모듈을 포함
make 및 make install: 소스 코드를 컴파일하고, 컴파일된 바이너리를 시스템에 설치

이 과정을 통해 원하는 기능을 가진 커스텀 Nginx를 빌드하여 사용할 수 있다.

1. 먼저 설치된 nginx의 버전을 확인해 본다.
설치된 폴더는 /usr/local/nginx/sbin 이므로
cd /usr/local/nginx/sbin
./nginx -v를 실행하면 
설치된 버전 확인이 가능하다.
네 경우 nginx version: nginx/1.12.2 로 나왔다.

2. wget 명령어나 curl 명령어로 파일을 다운 받는다.
난 curl로 다운받았다.
wget http://nginx.org/download/nginx-1.12.2.tar.gz
curl -O http://nginx.org/download/nginx-1.12.2.tar.gz

tar -xvf nginx-1.12.2.tar.gz

git clone https://github.com/arut/nginx-rtmp-module.git
cd nginx-1.12.2

Nginx 빌드시 필요한 의존성으로 사용되는 패키지 설치
libpcre3 및 libpcre3-dev: 정규 표현식을 사용하는 소프트웨어 개발을 위한 PCRE 라이브러리.
zlib1g-dev: 데이터 압축 및 해제를 위한 zlib 라이브러리 개발 파일.
libssl-dev: 보안 통신을 지원하는 OpenSSL 라이브러리 개발 파일.

yum install pcre pcre-devel
yum install zlib zlib-devel
yum install openssl openssl-devel

./configure --add-module=/usr/local/nginx/nginx-rtmp-module
make
make install

이제 ffmpeg 설치
1. EPEL 리포지토리 추가
yum install epel-release -y
참고로 실행 전 yum repolist | grep epel 으로 실행시 이미 설치되어있다면 미진행해도 됨
이런식으로 나옴
epel: ftp.kaist.ac.kr epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64  

2. FFmpeg는 기본적으로 CentOS/RHEL의 공식 저장소에는 포함되어 있지 않으므로 FFmpeg 설치를 위해 RPM Fusion 리포지토리 추가
yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm
yum localinstall --nogpgcheck https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-7.noarch.rpm

3. FFmpeg 설치
yum install ffmpeg ffmpeg-devel -y

4. FFmpeg 설치 확인
ffmpeg -version



만약 설치가 잘 안 된다면 아래 방법으로 시도
wget 또는 curl 설치하며 진행하면 되는데
yum install curl -y
curl -L -o ffmpeg-release-amd64-static.tar.xz https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz

압축 해제
tar xvf ffmpeg-release-amd64-static.tar.xz

압축 해제된 디렉토리로 이동
cd ffmpeg-*-amd64-static

FFmpeg 및 FFprobe 복사
해제된 디렉토리 내의 ffmpeg 및 ffprobe 파일을 /usr/local/bin으로 복사

cp ffmpeg /usr/local/bin/
cp ffprobe /usr/local/bin/

실행 권한 부여
chmod +x /usr/local/bin/ffmpeg
chmod +x /usr/local/bin/ffprobe

FFmpeg 버전 확인
ffmpeg -version
bash: /usr/bin/ffmpeg: 그런 파일이나 디렉터리가 없습니다 뜨면
ls -l /usr/local/bin/ffmpeg 로 확인

여기까지 진행됐다면 다음엔 nginx 설정을 진행한다.

반응형
Posted by Hippalus
,