일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 플래닛스케일
- nextjs
- nodemailer
- Nodejs
- PlanetScale
- 비디오전송
- 인스타그램API
- API루트
- next js
- 노드메일러
- pyinstaller
- ReactQuill
- mysqlworkbench
- pyqt5
- 쿠키관리
- 웹소켓
- expressjs
- state전역관리
- nextjs13
- 리액트
- 넥스트js
- APIroutes
- reactjs
- 인스타그램앱만들기
- 페이스북개발자
- socketIO
- 비디오스트리밍
- 앱비밀번호
- 넥스트JS13
- ReactContextAPI
- Today
- Total
Timpossible history
[Node JS] Express JS, 서버에서 클라이언트로 동영상 보내기(Feat. Streaming) 본문
웹사이트 구현 중, 대용량의 비디오 파일을 서버에서 전송을 해야하는 기능을 구현해야했다. 클라이언트 사이드에 파일을 저장시켜놓을 수가 없으니 서버에서 데이터 처리를 해야하는데, 이 서버에서 대용량 비디오의 데이터를 보내면서 재생시키도록 하기 위해서는 스트리밍 기능을 구현해야 한다. 이 포스트에서는 이 스트리밍 기능을 Express JS 기반 서버에서 구현해보도록 할 예정이다.
1. 프로젝트 시작
mkdir videoStreaming
cd videoStreaming
npm init -y
videoStreaming이라는 폴더를 만들어 이동해주고, npm init을 해준다.
그리고 프로젝트에 필요한 패키지를 설치해준다.
npm i express pug
express와 html 템플릿 엔진 pug를 설치해준다.
2. 소스코드 구현
1) 서버 사이드
// src/server.js
const express = require("express");
const fs = require("fs");
const videoPath = "video.mp4";
const app = express();
app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (req, res) => res.render("home"));
app.use("/video", (req, res) => {
const stat = fs.statSync(videoPath);
const fileSize = stat.size;
const range = req.headers.range;
if (range) {
const parts = range.replace(/bytes=/, "").split("-");
const start = parseInt(parts[0], 10);
const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
const chunkSize = end - start + 1;
const file = fs.createReadStream(videoPath, { start, end });
const headers = {
"Content-Range": `bytes ${start}-${end}/${fileSize}`,
"Accept-Ranges": "bytes",
"Content-Length": chunkSize,
"Content-Type": "video/mp4",
};
res.writeHead(206, headers);
file.pipe(res);
} else {
const headers = {
"Content-Length": fileSize,
"Content-Type": "video/mp4",
};
res.writeHead(200, headers);
fs.createReadStream(videoPath).pipe(res);
}
});
app.listen(8080, () => console.log("connected!"));
뷰 엔진은 pug로 세팅해주고, / 경로로 들어왔을 때 home.pug를 렌더링 할 수 있도록 세팅해주었다.
간단하게 클라이언트 사이드의 구현을 위해서 home.pug의 코드를 다음과 같이 짜주었다.
// src/views/home.pug
doctype html
html(lang="en")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title Home
link(rel="stylesheet", href="https://unpkg.com/mvp.css@1.12/mvp.css")
body
h1 This is home!
button#btn go watch video
script(src='/public/js/home.js')
// src/public/js/home.js
const button = document.querySelector("#btn");
button.addEventListener("click", (e) => {
e.preventDefault();
window.location = "/video";
});
home.pug와 연결한 script 코드는 간단하게 버튼을 눌렀을 때 /video 경로로 이동하도록 해준다.
// src/views/video.pug
doctype html
html(lang="en")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title video
link(rel="stylesheet", href="https://unpkg.com/mvp.css@1.12/mvp.css")
body
h1 Watch the video
video(width="640" height="360" controls)
source(src="http://localhost:8080/video" type="video/mp4")
p Your browser does not support the video tag.
/video의 경로로 이동하였을 때 서버에서는 미리 정해져있는 video 파일의 데이터를 스트리밍하여 클라이언트 사이드로 보내어 재생할 수 있도록 하는 것을 확인할 수 있다.
3. 참고
보통 서버에서도 여러 개의 대용량 비디오 파일을 다루기 쉽지 않기 때문에, 클라우드 서비스에 저장을 시켜놓고, 해당 비디오 파일의 경로를 DB에 저장하여 데이터를 불러올 때, 이 비디오가 저장되어 있는 클라우드의 url을 데이터베이스에서 불러와, 이를 스트리밍할 수 있도록 하는 것이 훨씬 효율적이다.
'백엔드 > Node JS' 카테고리의 다른 글
[Express JS] Socket.IO로 실시간 화상 채팅 구성(feat. WebRTC) (0) | 2024.01.04 |
---|---|
[Express JS] Socket.IO 이용해서 실시간 채팅 어플리케이션 구성 (0) | 2024.01.03 |
[Node JS] Nodemailer 사용 시 필요한 앱 비밀번호 설정 (0) | 2023.12.31 |