Skip to main content
0
Node.js

สร้างเซิร์ฟเวอร์สตรีมมิ่งวิดีโอด้วย Node.js เค้าทำยังไง?

สวัสดีครับทุกคน กลับมาพบกับบทความพื้นฐาน Back-End ง่าย ๆ สไตล์แอดเอฟกันอีกแล้ววว วันนี้เราจะมาสร้างเซิร์ฟเวอร์ที่เอาไว้สตรีมมิ่งวิดีโอด้วย Node.js กัน จะมีวิธีการเป็นยังไงไปดูกัน!

สำหรับโปรเจกต์ที่เราจะมาทำกันจะเป็นหน้าเว็บแบบง่าย ๆ ด้วยการใช้ HTML ที่มี video element โดยไปขอวิดีโอจาก API เส้น “/video” โดยตอนที่ขอวิดีโอไปเบราว์เซอร์จะแจ้งช่วงของข้อมูลที่ต้องการเป็นตัวเลย (เหมือนบอกว่าอยากดูวิดีโอตั้งแต่ตำแหน่งไหน)

ตัวอย่างเช่น ช่วงแรกของวิดีโอจะขอข้อมูลตั้งแต่ตำแหน่งที่ 0 เป็นต้นไป (เขียนว่า 0-) หลังจากนั้น เซิร์ฟเวอร์ก็จะส่ง status code 206 กลับมาเพื่อบอกว่าข้อมูลส่งมาแค่บางส่วน พร้อมทั้งช่วงของข้อมูล และ ขนาดของข้อมูลที่เซิร์ฟเวอร์ response กลับไปด้วย

ช่องของวิดีโอจะรู้ได้ว่าวิดีโอไม่ครบจาก response header แต่มันก็จะเล่นเท่าที่มันดาวน์โหลดมาได้ พอเล่นไปเรื่อย ๆ ช่องที่เล่นวิดีโอจะขอข้อมูลไปเพิ่มอีก เซิร์ฟเวอร์ก็จะส่งข้อมูลที่เบราเซอร์ขอมา ทำแบบนี้วนไปจนครบทั้งวิดีโอ

🚀 มาเริ่มทำโปรเจกต์ไปพร้อมกันเลย!

เปิด Terminal หรือ Command Prompt แล้วพิมพ์คำสั่งต่อไปนี้เพื่อสร้างโฟลเดอร์และเข้าไปในโฟลเดอร์ที่สร้างขึ้นใหม่

mkdir video-streaming
cd video-streaming

สร้างโปรเจกต์ Node.js ด้วย npm init เพื่อสร้างไฟล์ package.json ซึ่งเป็นไฟล์ที่ใช้จัดการ dependencies และข้อมูลของโปรเจกต์

npm init -y

ติดตั้งแพ็คเกจที่จำเป็น โดยในโปรเจกต์นี้ เราจะใช้ express ในการสร้างเซิร์ฟเวอร์

npm install express

สร้าง server โดยการเขียนในไฟล์ server.js ทำการเรียกใช้ Express.js และใช้ fs (file system) เพื่อจัดการกับไฟล์วิดีโอของเรา

const express = require("express");
const app = express();
const fs = require("fs");

จากนั้นเราจะสร้าง route สำหรับ root path (/) เพื่อเสิร์ฟไฟล์ index.html เมื่อมีการเข้าถึงหน้าเว็บ

app.get("/", function (req, res) {
  res.sendFile(__dirname + "/index.html");
});

จากนั้นกำหนด route เส้น /video ที่เป็น API หลักสำหรับการทำงานในบทความนี้ โดยเราจะทำการเช็ค header Range เพื่อให้แน่ใจว่ามี Request เพื่อขอช่วงของวิดีโอจาก Client ถ้าไม่มีเราจะส่ง Status Code 400 กลับไป

app.get("/video", function (req, res) {
  const range = req.headers.range;
  if (!range) {
    res.status(400).send("Requires Range header");
  }

หลังจากนั้นเราจะกำหนด path ของไฟล์วิดีโอและขนาดของไฟล์วิดีโอ

  const videoPath = "video.mp4";
  const videoSize = fs.statSync("video.mp4").size;

แล้วก็ทำการคำนวณขนาดของชิ้น (chunk) ที่จะส่งไป โดยเริ่มจากตำแหน่ง start ที่ได้จาก Range header และสิ้นสุดที่ end โดยขนาดเราสามารถกำหนดได้ โดยตัวอย่างนี้จะอยู่ที่ชิ้นละ 1MB

  const CHUNK_SIZE = 10 ** 6; // 1MB
  const start = Number(range.replace(/\D/g, ""));
  const end = Math.min(start + CHUNK_SIZE, videoSize - 1);

จากนั้นเราจะสร้าง headers ที่จำเป็นในการส่ง Response ไปยัง Client โดยใช้ Status Code เป็น 206 ซึ่งหมายถึง Partial Content แบบว่าเนื้อหายังไม่ครบ ยังมีต่อนะ

  const contentLength = end - start + 1;
  const headers = {
    "Content-Range": `bytes ${start}-${end}/${videoSize}`,
    "Accept-Ranges": "bytes",
    "Content-Length": contentLength,
    "Content-Type": "video/mp4",
  };

  res.writeHead(206, headers);

สุดท้ายเราจะสร้าง stream สำหรับวิดีโอจากตำแหน่ง start ถึง end แล้วทำการส่ง stream นั้นไปยังไคลเอ็นต์

const videoStream = fs.createReadStream(videoPath, { start, end });
  videoStream.pipe(res);
});

เป็นอันว่าจบฟังก์ชั่น สตรีมมิ่งวิดีโอเรียบร้อย แล้วก็อย่าลืมใส่ listen เพื่อบอกว่าให้ Server รันอยู่ที่ Port ไหนด้วย

app.listen(8000, function () {
  console.log("Listening on port 8000!");
});

โอเค! ฝั่งของ Back-End ก็จบไปเป็นที่เรียบร้อย ตอนรันเราก็สามารถใช้คำสั่ง node แล้วตามด้วยชื่อไฟล์ server.js ได้เลย หรือ ใครจะใช้ท่า nodemon หรืออื่น ๆ ก็ตามถนัด

ฝั่งของหน้าบ้าน

โดยในตัวอย่างนี้จะสร้างไฟล์ HTML ง่าย ๆ พร้อม CSS นิดหน่อยในไฟล์ index.html นี้เลย โค้ดที่มีก็จะประมาณนี้

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Video Streaming With Node</title>
    <style>
      body {
        margin: 5% auto;
        max-width: 100%;
        background-color: rgb(14, 14, 14);
        padding-top: 10%;
        padding-left: 35%;
      }
    </style>
  </head>
  <body>
    <video id="videoPlayer" width="50%" controls muted="muted" autoplay>
      <source src="/video" type="video/mp4" />
    </video>
  </body>
</html>

โดยหลัก ๆ แล้วโค้ดนี้คือเราสร้าง element <video> แล้วก็ไปเรียก /video มาโดยมีการตั้งค่านิด ๆ หน่อย ๆ คือให้มีตัวควบคุม แค่นี้เราก็ได้หน้าเว็บของเราก็จะสามารถเล่นวิดีโอได้แล้วนั่นเอง!

สำหรับใครที่อ่านมาถึงตรงนี้แล้ว อยากทำระบบแบบนี้ไปใช้งานร่วมกับ API ของตัวเอง แต่ยังไม่รู้จะเริ่มต้นยังไง? ตอนนี้หลักสูตร Road to Back-End Developer BootCamp รุ่นที่ 2 เปิดลงทะเบียนแล้ว!

Sirasit Boonklang

Author Sirasit Boonklang

More posts by Sirasit Boonklang

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

    ประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
    รายละเอียดคุกกี้

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า