Implementing HTTP live streaming with Object Storage and CDN
This guide explains how to implement a simple HLS (HTTP Live Streaming) example using KakaoCloud Object Storage and CDN. The process involves uploading HLS configuration files via the Object Storage API and deploying them through CDN.
- Estimated time: 25 minutes
- Recommended user environment:
- Operating system: macOS
- Region: kr-central-2
- Prerequisites:
- Python environment
- pip - Python package management tool
Prework
Install the FFmpeg package.
-
Run the following command to install
FFmpeg
, an open-source software that supports video file encoding and segmentation.Install ffmpegbrew install ffmpeg
-
To use Python FFmpeg, run the following command to install the
Python FFmpeg Video Streaming
package. This package is used for packaging media content for online streaming, such as DASH and HLS.Install Python FFmpeg Video Streamingpip install python-ffmpeg-video-streaming
Create Object Storage bucket & folder
For detailed examples on creating Object Storage buckets and folders, refer to the Uploading images using the Object Storage API document, specifically the sections on the Manage buckets via API calls and the Manage objects via API calls > Step 1. Create bucket.
- Write API call code in Python to create a bucket. Set the bucket name to
my-bucket-new
. - Write API call code in Python to manage access to the bucket. In this example, allow public access to all IP addresses for the bucket.
- Write API call code in Python to create a folder within the newly created bucket. Set the folder name to
hls
.
Create CDN
For detailed examples on configuring a CDN, refer to the Hosting static website using Object Storage and CDN document, specifically the section on Step 4. Set up CDN.
-
Go to KakaoCloud Console > CDN and create a new CDN.
Step 1: Configure service and origin server
Item Value Service Name hls-test-cdn Host Server KiC CDN Origin Server KakaoCloud object storage
- Select bucket: my-bucket-newOrigin Server Protocol HTTPS Origin Server Port Number 443 Origin Server Path /hls Gzip Compression Enabled Step 2: Configure cache
Item Value Expiration Policy Custom Retention Period 3 seconds URL Query String Included Image (JPG) File Optimization - -
Click the [More] icon and select Start or Restart to start the CDN service.
Step 1. Create and upload the example static website
Create static website
-
Run the following command to create the working directory.
Create working directorymkdir -p ~/hls-handson
-
Refer to the HTML example below to create an HTML file for web access. Use the open-source JavaScript library Hls.js to implement HLS.
- This is a simple static website that displays text and video. The
video
tag in HTML5 is used, and thesrc
attribute of thevideo
tag is set to 'hls.m3u8'. This will be the access path for the hls.m3u8 file that you will generate in a later step.
Static website examplecat <<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 - This is a simple static website that displays text and video. The
Upload the example site via API calls
In this step, you'll write code in Python. Create a Python file (.py
) inside the hls-handson
folder generated in [Step 1] and proceed with the task in that file.
-
Write Python code to make an API call to upload the
index.html
file to the Object Storage folder created during the preliminary steps.Upload index.html fileimport 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()Variable Description Example Value X_AUTH_TOKEN API authentication token FILE_PATH Path to the file. In this exercise, the path to the index.html file index.html ACCOUNT Project ID
- Available when the token is issued
- Value of token > project > id in the response bodyBUCKET_NAME Name of the bucket where the file will be uploaded my-bucket-new FOLDER_NAME Name of the folder where the file will be uploaded hls FILE_NAME Name of the file to be created (uploaded) index.html -
After running the code, go to the KakaoCloud Console > Object Storage service and select the
my-bucket-new
bucket. -
In the Objects tab, confirm that the
index.html
file has been uploaded inside thehls
folder.
Verify access to example site
Access the index.html path of the CDN service domain.
-
In the KakaoCloud Console > CDN > Service List, copy the service domain of the created CDN.
-
Use a web browser to verify normal access to the test page.
# Service address to connect to
http://{URL generated by CDN}/index.html -
When you access the domain, text is displayed. The video is not displayed because the files required for streaming are not yet prepared. CDN service domain access result
Step 2. Upload HLS configuration file to bucket
Prepare video file
Run the code below in the local terminal to download the video file (kakaoenterprise.mp4
) for streaming to the local ~/hls-handson
folder.
curl -o ~/hls-handson/kakaoenterprise.mp4 \
https://objectstorage.kr-central-2.kakaocloud.com/v1/fe631cd1b7a14c0ba2612d031a8a5619/public/tutorial/hls-live-streaming/kakaoenterprise.mp4
Encode and segment video files (.MP4) with FFmpeg
In this step, we will write code in Python. Create a Python file (.py) in the hls-handson
folder created in [Step 1] and work on it.
-
In order to provide video with HLS, you need an
m3u8
file containing playback information and ats
file that is a small segment of the original video. You can convert the original video file (.mp4) by running the code below to create anm3u8
file and ats
file by quality.Video file conversion commandimport 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')Variable Description Practice Setting Value MP4_FILE_PATH Path where mp4 file is located kakaoenterprise.mp4 -
When the code is executed,
m3u8
files andts
files for each quality are created in the~/hls-handson/output
folder as shown in the folder structure below.Folder Structureoutput/
├── hls.m3u8
├── hls_360p.m3u8
├── hls_360p_0000.ts
├── …
├── hls_480p.m3u8
├── hls_480p_0000.ts
├── …
├── hls_720p.m3u8
├── hls_720p_0000.ts
└── …
Upload m3u8 and ts files to bucket using Object Storage API
Write an API call code to upload files to an Object Storage bucket and upload the m3u8
and ts
files in the hls
folder of the my-bucket-new
bucket.
-
When calling the file upload API, you must enter a MIME type string in the
Content-Type
ofheaders
. Form3u8
, setContent-Type
toaudio/mpegurl
type, and forts
files, setContent-Type
toapplication/octet-stream
type.File upload API call codeimport 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()Variable Description Practice setting value OUTPUT_FOLDER_PATH Path of the output folder where the m3u8 and ts files are located output BUCKET_NAME Bucket name where the files will be uploaded my-bucket-new FOLDER_NAME Folder name where the files will be uploaded hls -
After running the code, select the
my-bucket-new
bucket in KakaoCloud Console > Object Storage. -
In the Object tab, you can check that the
m3u8
andts
files have been uploaded in thehls
folder.
Step 3. Check video output
Check whether the video uploaded from the domain is output properly. Access the index.html
path of the CDN service domain and check the output video.
# Service domain address to connect to
http://{URL generated by CDN}/index.html
Service domain accessed