ทำ Video On-Demand ด้วย Nginx VOD Module

ทำ Video On Demand Streaming โดยใช้ Kaltura’s nginx vod module ซึ่งมีความสามารถในการ stream ไฟล์วีดีโอ mp4 ไปเป็นฟอร์แมตต่างๆ เช่น DASH, HDS, HLS, MSS นอกจากนี้ยังสามารถเพิ่มฟังก์ชั่นอื่นๆได้เช่น การทำ authentication, การ stream แบบ multi-bitrate, การใส่ subtitle, การทำ thumbnail เป็นต้น

เตรียมความพร้อมเซิฟเวอร์และลงโปรแกรมที่ต้องใช้

ในที่นี้จะเป็นการลงไปยังเซิฟเวอร์ Ubuntu บน Amazon EC2 โดยใช้คำสั่งดังนี้

sudo apt update && sudo apt upgrade -y

sudo apt install curl build-essential libssl-dev zlib1g-dev linux-generic linux-headers-$(uname -r) libpcre3 libpcre3-dev ffmpeg libavcodec-dev libavformat-dev libswscale-dev -y

ลง Nginx และ Module ต่างๆ

เราจะเริ่มลง Nginx โดยจะ build พร้อม module ต่างๆ ดังนี้

  • Kaltura’s vod module เป็นโมดูลหลักที่ใช้ในการทำ On-the-fly repackaging วีดีโอ mp4
  • Akamai token validation module ใช้ในการ validate token ใน url ของวีดีโอ (เพื่อใช้ในการทำ authentication)
  • Secure token module ใช้ในการสร้าง (generate) token สำหรับใช้ใน url

เริ่มต้นจากการสร้าง folder เพื่อเตรียมดาวน์โหลดและแตกไฟล์

mkdir nginx nginx-vod-module nginx-akamai-token-validate-module nginx-secure-token-module

จากนั้นทำการดาวน์โหลดและแตกไฟล์ nginx และ module ต่างๆ

curl -sL https://nginx.org/download/nginx-1.16.1.tar.gz | tar -C /home/ubuntu/nginx --strip 1 -xz
curl -sL https://github.com/kaltura/nginx-vod-module/archive/399e1a0ecb5b0007df3a627fa8b03628fc922d5e.tar.gz | tar -C /home/ubuntu/nginx-vod-module --strip 1 -xz
curl -sL https://github.com/kaltura/nginx-akamai-token-validate-module/archive/1.1.tar.gz | tar -C /home/ubuntu/nginx-akamai-token-validate-module --strip 1 -xz
curl -sL https://github.com/kaltura/nginx-secure-token-module/archive/1.4.tar.gz | tar -C /home/ubuntu/nginx-secure-token-module --strip 1 -xz

ทำการ configure, make และ make install เพื่อลง

cd nginx 

./configure --prefix=/usr/local/nginx \
	--add-module=../nginx-vod-module \
	--add-module=../nginx-akamai-token-validate-module \
	--add-module=../nginx-secure-token-module \
	--with-http_ssl_module \
	--with-file-aio \
	--with-threads \
	--with-cc-opt="-O3"

sudo make
sudo make install

sudo rm -rf /usr/local/nginx/html /usr/local/nginx/conf/*.default

เมื่อลงเรียบร้อยแล้ว ทดสอบ nginx โดยเริ่มต้นการทำงานของ nginx

sudo /usr/local/nginx/sbin/nginx

แล้วลองเข้าหน้าเว็บที่ IP ของเซิฟเวอร์ หาก nginx รันสำเร็จ จะปรากฎหน้า Error 404 Not Found

ตั้งค่าเซิฟเวอร์ Nginx และโมดูล

เมื่อลง nginx เรียบร้อยแล้ว ก็ต้องทำการตั้งค่าไฟล์ nginx.conf เพื่อให้สามารถทำงานได้ตามที่เราต้องการ โดยสร้างไฟล์ไปที่ /usr/local/nginx โดย

sudo vi /usr/local/nginx/conf/nginx.conf

ซึ่งเราจะตั้งค่า ดังนี้

  • เล่นไฟล์ mp4 จากในโฟลเดอร์หนึ่งในเซิฟเวอร์ (local file system)
  • Output ฟอร์แมทเป็น hls
  • สามารถสร้าง thumbnail เป็นรูปภาพจากวีดีโอเพื่อพรีวิวได้
  • มีการทำรักษาความปลอดภัยด้วย token ที่สร้างจากโปรแกรมปลายทางโดยใช้ key เป็น random hex ที่ตั้งไว้ (generate random hex มาโดยใช้เครื่องมือ เช่น browserling tools/random-hex)

ไฟล์ nginx.conf เต็ม ดังนี้

worker_processes  auto;
user ubuntu;
pid /run/nginx.pid;

events {
	use epoll;
}

http {
	log_format  main  '$remote_addr $remote_user [$time_local] "$request" '
		'$status "$http_referer" "$http_user_agent"';

	access_log  /home/ubuntu/nginx.log  main;
	error_log   stderr debug;

	default_type  application/octet-stream;
	include       /usr/local/nginx/conf/mime.types;

	sendfile    on;
	tcp_nopush  on;
	tcp_nodelay on;

	vod_mode                           local;
	vod_metadata_cache                 metadata_cache 16m;
	vod_response_cache                 response_cache 512m;
	vod_last_modified_types            *;
	vod_segment_duration               9000;
	vod_align_segments_to_key_frames   on;
	vod_dash_fragment_file_name_prefix "segment";
	vod_hls_segment_file_name_prefix   "segment";

	vod_manifest_segment_durations_mode accurate;

	open_file_cache          max=1000 inactive=5m;
	open_file_cache_valid    2m;
	open_file_cache_min_uses 1;
	open_file_cache_errors   on;

	aio on;
	
	secure_token_akamai $secure_token {
		key RANDOM_HEX;
		acl "$secure_token_baseuri_comma*";
		param_name token;
	}

	server {
		listen 80;
		server_name localhost;
		root /home/ubuntu;

		location ~ ^/videos/.+$ {
			autoindex on;
		}

		location /hls/ {
			vod hls;
			alias /home/ubuntu/videos/;
			
			if ($arg_token) {
			  set $input_token $arg_token;
			}
			
			add_header Access-Control-Allow-Headers '*';
			add_header Access-Control-Allow-Origin '*';
			add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';

			akamai_token_validate $input_token;
			akamai_token_validate_key RANDOM_HEX;

			secure_token $secure_token;
			secure_token_types application/vnd.apple.mpegurl;
			secure_token_expires_time 100d;
			secure_token_query_token_expires_time 1h;
		}

		location /thumb/ {
			vod thumb;
			alias /home/ubuntu/videos/;
			add_header Access-Control-Allow-Headers '*';
			add_header Access-Control-Allow-Origin '*';
			add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
		}
	}
}

โดยจะต้องแก้ไขข้อมูลให้เป็นไปตามค่าที่เราต้องการใช้ ได้แก่

  • ค่า RANDOM_HEX ต้อง generate มาใหม่จากเครื่องมือ เช่น browserling tools/random-hex
  • ค่า root คือ
  • ค่า alias ใน location /hls/ และ /thumb/ ให้ตรงกับโฟลเดอร์ที่เก็บไฟล์วีดีโอ
  • ค่าอื่นๆ เช่น access_log และ error_log ไฟล์

เมื่อตั้งค่าต้องรีโหลด nginx โดยใช้คำสั่ง

/usr/local/nginx/sbin/nginx -s reload

การทดสอบ

จะสามารถทดสอบได้เมื่อมีไฟล์วีดีโอก่อน โดยให้นำวีดีโอสำหรับเทสไปไว้ที่โฟลเดอร์ที่ตั้งเป็นค่า alias ใน location ที่ตั้งไว้ในไฟล์ nginx.conf เช่นตามตัวอย่าง location เป็น /home/ubuntu/videos ก็จะนำไฟล์ video.mp4 ไปใส่ไว้ในโฟลเดอร์ดังกล่าว

ทดสอบภาพตัวอย่าง (Thumbnail)

เริ่มโดยการทดสอบภาพตัวอย่างก่อน โดยลองเปิด url ไปที่
http://YOUR_IP/thumb/video.mp4/thumb-300.jpg
ตัวเลขหลัง thumb- คือเวลาในวีดีโอที่ต้องการจับภาพมา หากใช้งานได้ปกติก็จะปรากฎรูปภาพจากวีดีโอที่เวลานั้นๆ

ทดสอบวีดีโอ

การทำสอบวีดีโอจะทำการทดสอบโดยใช้โปรแกรมที่สามารถดู video streaming ได้ ซึ่งในที่นี้จะใช้ VLC media player แต่เนื่องจากการเล่นวีดีโอนี้เรามีการรักษาความปลอดภัยโดย token จึงต้องสร้าง URL ที่มี token ขึ้นมาก่อน โดยใช้เครื่องมือ เช่น matricali/php-edge-auth

ซึ่ง token จะมีการกำหนดเวลาหมดอายุ และ generate ออกมาได้เช่น exp=1553295434~acl=%2f*~hmac=5a6253*******9d5cbe73

ให้นำไปต่อท้าย url ของวีดีโอ ดังนี้
http://YOUR_IP/hls/video.mp4,.urlset/master.m3u8?token=exp=1553295434~acl=%2f*~hmac=5a6253*******9d5cbe73

สามารถนำไปทดลองใน VLC ได้โดยไปที่ File > Open Network แล้วใส่ URL เต็มเพื่อ open

หากใช้งานได้ โปรแกรม VLC จะเล่นไฟล์วีดีโอนั้นๆขึ้นมา

หมายเหตุ: การลง Nginx ตามวิธีข้างต้นนี้ หากเปิดปิดรีสตาร์ทเครื่องเซิฟเวอร์แล้ว nginx จะไม่เปิดขึ้นมาโดยอัตโนมัติ โดยสามารถตั้งค่าให้เปิดอัตโนมัติได้โดยสร้างให้เป็น systemd service โดยสามารถดูวิธีได้ในโพส ตั้งค่าให้ Nginx เป็น Systemd service ใน Ubuntu