HLS 스트리밍 서버 구현
영상 링크
- 실습 1~3 진행 시연 영상
- 과제 진행 시연 영상
영상 소리가 작게 녹음됨
실습1: 간단한 HLS 비디오 직접 만들기
1) 사용 명령어
docker build -t hls-server .
docker run -d -p 8080:8080 --name hls-server hls-server tail -f /dev/null
docker exec -it hls-server /bin/bash
apt-get update
apt-get install -y nginx
mkdir -p /var/www/html/hls
mkdir /workspace/videos
ffmpeg -f lavfi -i testsrc=duration=5:size=640x480:rate=30 \
-pix_fmt yuv420p \
/workspace/videos/test.mp4
ffmpeg -i /workspace/videos/test.mp4 \
-codec:v libx264 \
-hls_time 2 \
-hls_list_size 0 \
/var/www/html/hls/test.m3u8
docker cp hls-server:/workspace/videos/test.mp4 ./test.mp4
실습2: HLS 음성 링크 추출
사용 명령어
ffmpeg -i 'https://1fm.gscdn.kbs.co.kr/1fm_192_2.m3u8?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly8xZm0uZ3NjZG4ua2JzLmNvLmtyLyoiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE3NjM5NzkxMTZ9fX1dfQ__&Key-Pair-Id=APKAICDSGT3Y7IXGJ3TA&Signature=Cx5dhvU~s0fSD5rIW-AlFo0uBRO7AwS1aXdCotdsKBXuDEKPUgt4H~~g5D80HKHwjKMezl7OlCl2mVYIfHAK64eU2LzTnY9N8YDcwbXsXOVIIsuZWKlCzVVMMckWwCUFjLt95WCNtdy4JWp5Fd9YqKrJddx7M-IEVjeuqKdQ6LmLG2QFUwDjudk9iinEB13PjiH56CW397Szh0CWM7dv5PdPU902vFHIoDLYfK-aFYbR2KMajlovEb-cosujFwXVgSUZ8-CbNrRfgmE7xOO9XOq2pXA9BN38vcyUwZL~hxxPjtxjJVQAQBzuerfaCZWUN72J5G8brRlXc0z3uv7GYg__' \
-t 180 \
kbs-1fm-3min.mp3
실습3: 추출한 HLS음성을 넣은 nginx Web Server
1) 기타 참고사항
- 강의자료 실습1 부분에서 컨테이너 포트 매핑이 8080:8080으로 되어있어, nginx기본 포트(80)로 매핑한 컨테이너 새로 만들어 진행함.
- 웹에 화면 띄울 때 음성파일이 잘 로드되었는데도 상태(textContent) 글자가 바뀌지 않았음. 제공된 index.html Line 50에
<script>내부에status변수가 있는데,window.status예약어랑 겹쳐서 제대로 코드가 동작을 안했던 것 같음. 따라서status변수를status_로 바꾸어 정상적으로 페이지에 바뀐 텍스트가 반영되도록 함.
2) 사용 명령어 및 웹 접속 주소
docker run -d -p 8080:80 --name hls-server hls-server tail -f /dev/null
docker exec -it hls-server /bin/bash
apt-get update
apt-get install -y nginx
mkdir -p /var/www/html/hls
mkdir /workspace/videos
mkdir -p /var/www/html/stream
exit
docker cp "/Users/clr/Desktop/CNU/CNU 3-2/컴네/W12/lab/index.html" hls-server:/var/www/html/index.html
docker exec -it hls-server /bin/bash
ffmpeg -i \
'https://1fm.gscdn.kbs.co.kr/1fm_192_2.m3u8?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly8xZm0uZ3NjZG4ua2JzLmNvLmtyLyoiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE3NjM5NzkxMTZ9fX1dfQ__&Key-Pair-Id=APKAICDSGT3Y7IXGJ3TA&Signature=Cx5dhvU~s0fSD5rIW-AlFo0uBRO7AwS1aXdCotdsKBXuDEKPUgt4H~~g5D80HKHwjKMezl7OlCl2mVYIfHAK64eU2LzTnY9N8YDcwbXsXOVIIsuZWKlCzVVMMckWwCUFjLt95WCNtdy4JWp5Fd9YqKrJddx7M-IEVjeuqKdQ6LmLG2QFUwDjudk9iinEB13PjiH56CW397Szh0CWM7dv5PdPU902vFHIoDLYfK-aFYbR2KMajlovEb-cosujFwXVgSUZ8-CbNrRfgmE7xOO9XOq2pXA9BN38vcyUwZL~hxxPjtxjJVQAQBzuerfaCZWUN72J5G8brRlXc0z3uv7GYg__' \
-t 60 \
-c:a aac \
-b:a 128k \
-hls_time 10 \
-hls_list_size 0 \
-hls_segment_filename '/var/www/html/stream/segment%03d.ts' \
/var/www/html/stream/playlist.m3u8
service nginx start
웹 접속: http://localhost:8080
과제: 영상이 들어간 웹 서버 구현
1) index.html 수정
- 코드를 비디오용으로 수정(audio→video)
2) 영상 HLS 링크 찾기

- 나는 KBS 1박2일 영상의 HLS 링크를 찾을 것이다.
- Chrome에서 진행했다.

- 개발자도구→Network로 들어간다. 브라우저와 서버 사이에서 오가는 모든 HTTP 요청을 볼 수 있기 때문에, HLS주소를 포함한 요청 또한 찾을 수 있다.
- Fetch/XHR과 “channel”필터를 넣고 브라우저를 새로고침해준다. 페이지에는 이미지, css, js 등 다양한 리소스 요청이 섞여 있다. HLS 주소는 보통 JSON 응답이나 API 호출 안에 포함되어 있는데, 이런 것들은 대부분 XHR / Fetch 요청으로 전달된다. 따라서 Fetch/XHR만 남기면 결과를 줄여서 볼 수 있어 효율적이다.
- 그런 다음 상단 검색창에 channel을 입력하여 필터링한다. KBS는 채널 정보를 주고받을 때 요청 URL이나 응답 JSON 안에 channel같은 이름을 사용한다. 검색창에 channel을 입력하면, 여러 개의 XHR이 채널 설정과 관련된 요청들로 줄어들게 되고, 그 안에서 HLS 주소를 빠르게 찾을 수 있다.

- 페이지를 새로고침하여 HLS주소를 주는 API 요청을 발생시킨다.
- 채널코드 N93을 찾고, response 탭에서 channel_item을 찾는다. 그리고 그 안에 있는 service_url을 찾아, HLS 재생 주소를 가져온다.
3) 사용 명령어 및 웹 접속 주소
docker run -d -p 8080:80 --name hls-server hls-server tail -f /dev/null
docker exec -it hls-server /bin/bash
apt-get update
apt-get install -y nginx
mkdir -p /var/www/html/hls
mkdir /workspace/videos
mkdir -p /var/www/html/stream
exit
docker cp "/Users/clr/Desktop/CNU/CNU 3-2/컴네/W12/lab/index.html" hls-server:/var/www/html/index.html
docker exec -it hls-server /bin/bash
ffmpeg -i \
'https://kbsnlife.gscdn.kbs.co.kr/kbsnlife-02/kbsnlife-02_sd.m3u8?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9rYnNubGlmZS5nc2Nkbi5rYnMuY28ua3Iva2JzbmxpZmUtMDIvKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc2Mzk4NjQ1Mn19fV19&Key-Pair-Id=APKAICDSGT3Y7IXGJ3TA&Signature=Xy8rNSo8xTmHERqk0q2VHgN3AgkdR0DCKvetVhP1ldGBhjXnOcvVb4PLOij9Zk18uk~w~pNIIksMFw06uJ~k-9qmHmsZCT4edHv7HXVmTtcWE37PRZZPf5tG1rJNHoqc3CtPSYg557UuAUXhQPwrOpmlrfn~jZTRAQg5rBogOgWSgfc1SahPCCNYXJZtZ3Fdq9w66y2Us5CISQ3-MlgOGfm3oUiuVVyPx9MCMgS8AgWresjgdJY6UAxVbgKSVppSe9mfGZuJ8bdmDOmtqbL55rEyCX~tX9XFAPe6Xo0GRjNaPhxuBnQXyrf6YpGgVv7zllkWtKRGuJQc7O74Tmxrdg__' \
-t 60 \
-c:a aac \
-b:a 128k \
-hls_time 10 \
-hls_list_size 0 \
-hls_segment_filename '/var/www/html/stream/segment%03d.ts' \
/var/www/html/stream/playlist.m3u8
service nginx start
웹 접속: http://localhost:8080
Leave a comment