Object Storage와 CDN으로 HTTP Live Streaming 구현
카카오클라우드 Object Storage와 CDN을 이용하여 간단한 HLS(HTTP Live Streaming) 예제를 구현하는 방식을 설명합니다. Object Storage API를 통해 코드 기반으로 HLS 구성 파일을 업로드하고, CDN을 통해 배포하여 진행합니다.
- 예상 소요 시간: 25분
- 사용자 환경
- 권장 운영 체제: MacOS
- Region: kr-central-2
- 사전 준비 사항
- Python 실행 환경 설정
- pip: Python 패키지 관리 도구 설치
시작하기 전에
1. FFmpeg 관련 패키지 설치
-
아래 명령을 실행하여 비디오 파일 인코딩과 segmentation을 지원하는 오픈소스 소프트웨어인
FFmpeg
을 설치합니다.ffmpeg 설치brew install ffmpeg
-
Python FFmpeg를 사용하기 위해 아래의 명령을 실행해
Python FFmpeg Video Streaming
패키지를 설치합니다. 해당 패키지는 DASH 및 HLS와 같은 온라인 스트리밍을 위한 미디어 콘텐츠를 패키지화합니다.Python FFmpeg Video Streaming 설치pip install python-ffmpeg-video-streaming
2. Object Storage 버킷 생성
Object Storage 버킷 & 폴더 생성에 대한 자세한 예제는 Object Storage API를 이용하여 이미지 업로드하기 문서의 API 호출로 버킷 관리와 API 호출로 오브젝트 관리 > Step 1. 버킷 생성하기를 참고하시기 바랍니다.
- Python으로 버킷(Bucket)을 생성하는 API 호출 코드를 작성하여 버킷을 생성합니다. 버킷 이름은
my-bucket-new
로 설정합니다. - Python으로 버킷에 대한 접근을 관리하는 API 호출 코드를 작성하여 버킷에 대한 접근을 관리합니다. 이번 예제에서는 버킷에 대한 모든 IP 주소의 퍼블릭 액세스를 허용합니다.
- Python으로 생성한 버킷 안에 폴더를 생성하는 API 호출 코드를 작성하여 폴더를 생성합니다. 폴더 이름은
hls
로 설정합니다.
3. CDN 생성
CDN 설정하기에 대한 자세한 예제는 Object Storage, CDN을 이용한 정적 웹사이트 호스팅하기 문서의 Step 4. CDN 설정하기를 참고하시기 바랍니다.
-
카카오클라우드 콘솔 > Beyond Networking Service > CDN에서 CDN을 생성합니다.
1단계: 서비스 및 오리진 서버 설정
항목 값 서비스 이름 hls-test-cdn 호스트 서버 KiC CDN 오리진 서버 KakaoCloud object storage
- 버킷: my-bucket-new 선택오리진 서버 프로토콜 HTTPS 오리진 서버 포트 번호 443 오리진 서버 경로 /hls Gzip Compression 사용 2단계: 캐시 설정
항목 값 만료 정책 사용자 설정 유지 기간 3 초 URL Query String 포함 이미지(JPG) 파일 최적화 - -
생성된 CDN 서비스의 [더 보기] 아이콘 > 시작 또는 재시작을 클릭해 CDN 서비스를 시작합니다.
시작하기
Step 1. 예제 정적 웹 사이트 생성 및 업로드
1. 예제 정적 웹 사이트 생성하기
-
아래 명령을 실행하여 작업 디렉터리를 생성합니다.
작업 디렉터리 생성mkdir -p ~/hls-handson
-
하단의 html 예제를 참고하여 접근 웹 html 파일을 작성합니다. HLS 구현을 위해 오픈소스 자바스크립트 라이브러리인 Hls.js를 이용합니다.
- 텍스트와 영상을 출력하는 간단한 정적 웹 사이트입니다. HTML5의
video
태그를 이용하고,video
태그의 소스(src
) 속성은 'hls.m3u8'로 설정합니다. 이는 추후 과정에서 생성할 hls.m3u8 파일의 접근 경로입니다.
정적 웹사이트 출력 예제cat <<EOF > ~/hls-handson/index.html
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body onkeydown="return false" oncontextmenu="return false" onselectstart="return false" ondragstart="return false">
<h1>HLS Test Page</h1>
<video height="720" width="1280" autoplay muted id="video"></video>
<script>
var video = document.getElementById('video');
var videoSrc = 'hls.m3u8';
if (video.canPlayType('application/x-mpegURL')) {
video.src = videoSrc;
} else if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
}
</script>
</body>
</html>
EOF - 텍스트와 영상을 출력하는 간단한 정적 웹 사이트입니다. HTML5의
2. API 호출로 예제 사이트 업로드하기
본 단계에서는 Python으로 코드를 작성합니다. [Step 1]에서 생성한 hls-handson
폴더 안에 Python 파일(.py
)을 생성해 해당 파일에서 작업을 진행합니다.
-
사전 작업에서 생성한 Object Storage 폴더 안에
index.html
파일을 업로드하는 API 호출 Python 코드를 작성합니다.index.html 파일 업로드import requests
def uploadFile():
headers = {
'X-Auth-Token': '{X_AUTH_TOKEN}',
'Content-Type': 'text/html'
}
data = open('{FILE_PATH}', 'rb')
res = requests.put('https://objectstorage.kr-central-2.kakaocloud.com/v1/{ACCOUNT}/{BUCKET_NAME}/{FOLDER_NAME}/{FILE_NAME}', headers=headers, data=data)
data.close()
uploadFile()변수 설명 실습 설정값 X_AUTH_TOKEN API 인증 토큰 FILE_PATH 파일이 위치한 경로. 이번 실습에서는 index.html 파일이 위치한 경로 index.html ACCOUNT 프로젝트 ID
- 토큰 발급 시 확인 가능
- Response Body의 token > project > id 값BUCKET_NAME 파일이 업로드될 버킷 이름 my-bucket-new FOLDER_NAME 파일이 업로드될 폴더 이름 hls FILE_NAME 생성(업로드)할 파일 이름 index.html -
코드 실행 후,카카오클라우드 콘솔 > Object Storage 서비스에서
my-bucket-new
버킷을 선택합니다. -
객체 탭에서
hls
폴더 안에index.html
파일이 업로드된 것을 확인합니다.
3. 예제 사이트 접속 확인하기
CDN 서비스 도메인의 index.html 경로로 접속합니다.
-
카카오클라우드 콘솔 > Beyond Networking Service > CDN > 서비스 목록에서 생성된 CDN의 서비스 도메인을 복사합니다.
-
웹 브라우저에서 테스트 페이지로의 정상 접속을 확인합니다.
# 접속할 서비스 도메인 주소
http://{CDN에서 생성한 URL}/index.html -
도메인 접속 시 텍스트가 출력됩니다. 스트리밍에 필요한 파일이 아직 준비되지 않았으므로 영상은 출력되지 않습니다.
CDN 서비스 도메인 접속 결과
Step 2. 버킷에 HLS 구성 파일 업로드하기
1. 동영상 파일 준비하기
로컬 터미널에서 아래의 코드를 실행하여 로컬의 ~/hls-handson
폴더에 스트리밍을 위한 동영상 파일(kakaoenterprise.mp4
)을 다운로드합니다.
curl -o ~/hls-handson/kakaoenterprise.mp4 \
https://objectstorage.kr-central-2.kakaocloud.com/v1/fe631cd1b7a14c0ba2612d031a8a5619/public/tutorial/hls-live-streaming/kakaoenterprise.mp4
2. FFmpeg으로 동영상 파일(.MP4) 인코딩 및 Segmentation하기
본 단계에서는 Python으로 코드를 작성합니다. [Step 1]에서 생성한 hls-handson
폴더 안에 Python 파일(.py)을 생성해 해당 파일에서 작업을 진행합니다.
-
HLS로 영상을 제공하기 위해서는 재생 정보가 담긴
m3u8
파일과 원본 영상을 잘게 분할한ts
파일이 필요합니다. 아래 코드를 실행하여 원본 동영상 파일(.mp4)을 변환해m3u8
파일과ts
파일을 화질 별로 생성할 수 있습니다.동영상 파일 변환 명령어import ffmpeg_streaming
from ffmpeg_streaming import Formats, Bitrate, Representation, Size
capture = ffmpeg_streaming.input('{MP4_FILE_PATH}')
_360p = Representation(Size(640, 360), Bitrate(276 * 1024, 128 * 1024))
_480p = Representation(Size(854, 480), Bitrate(750 * 1024, 192 * 1024))
_720p = Representation(Size(1280, 720), Bitrate(2048 * 1024, 320 * 1024))
hls = capture.hls(Formats.h264())
hls.representations(_360p, _480p, _720p)
hls.output('output/hls.m3u8')변수 설명 실습 설정값 MP4_FILE_PATH mp4 파일이 위치한 경로 kakaoenterprise.mp4 -
코드 실행 시 하단의 폴더 구조와 같이
~/hls-handson/output
폴더 내에 화질 별m3u8
파일과ts
파일들이 생성됩니다.폴더 구조output/
├── hls.m3u8
├── hls_360p.m3u8
├── hls_360p_0000.ts
├── …
├── hls_480p.m3u8
├── hls_480p_0000.ts
├── …
├── hls_720p.m3u8
├── hls_720p_0000.ts
└── …
3. Object Storage API를 이용하여 버킷에 m3u8, ts 파일 업로드하기
Object Storage 버킷에 파일을 업로드하는 API 호출 코드를 작성하여 my-bucket-new
버킷의 hls
폴더 안에 m3u8
파일과 ts
파일을 업로드합니다.
-
파일 업로드 API 호출 시
headers
의Content-Type
에는 MIME type 문자열을 입력해야 합니다.m3u8
은audio/mpegurl
유형으로,ts
파일은application/octet-stream
유형으로Content-Type
을 설정합니다.파일 업로드 API 호출 코드import requests
import os
def uploadHlsFile():
headers = {'X-Auth-Token': '{X_AUTH_TOKEN}'}
for file in os.listdir('{OUTPUT_FOLDER_PATH}'):
file_extension = file.split('.')[1]
if file_extension == 'm3u8':
headers['Content-Type'] = 'audio/mpegurl'
if file_extension == 'ts':
headers['Content-Type'] = 'application/octet-stream'
data = open('{OUTPUT_FOLDER_PATH}'+'/'+file, 'rb')
res = requests.put('https://objectstorage.kr-central-2.kakaocloud.com/v1/{ACCOUNT}/{BUCKET_NAME}/{FOLDER_NAME}/'+file, headers=headers, data=data)
if res.status_code == 201:
print("File upload succeeded: " + file)
else:
print("File upload failed: " + file)
data.close()
uploadHlsFile()변수 설명 실습 설정값 OUTPUT_FOLDER_PATH m3u8, ts 파일이 위치한 output 폴더의 경로 output BUCKET_NAME 파일이 업로드될 버킷 이름 my-bucket-new FOLDER_NAME 파일이 업로드될 폴더 이름 hls -
코드 실행 후, 카카오클라우드 콘솔 > Object Storage 서비스에서
my-bucket-new
버킷을 선택합니다. -
객체 탭에서
hls
폴더 안에m3u8
파일과ts
파일이 업로드된 것을 확인할 수 있습니다.
Step 3. 영상 출력 확인하기
도메인에서 업로드한 영상이 잘 출력되는지 확인합니다. CDN 서비스 도메인의 index.html
경로로 접근하여 출력된 영상을 확인합니다.
# 접속할 서비스 도메인 주소
http://{CDN에서 생성한 URL}/index.html
서비스 도메인 접속 결과