webcam Diary Side Project - back end

김민섭·2023년 1월 12일
0

이번편 은 파일을 백엔드쪽으로 넘겨 저장하고 출력하는 작업을 진행하겠습니다.

 폴더 생성
mkdir "디렉토리명"

 패키지 설치
npm init 

 백엔드 구현을 위한 express install 
npm i express

 파일업로드를 도와줄 라이브러리
npm i express-fileupload

 크로스브라우징 문제를 해결
npm i core

 실시간 갱신을 위한 library 
npm i nodemon

위 해당과정을 진행하고 package.json에서 시작 구문을 아래와 같이 변경해줍니다.

nodemon으로 해당 기능을 실행하여 코드의 변화를 실시간으로 인식하기 위함입니다.

nodemon --watch index.js

이후

현재 디렉토리에 index.js 파일을 추가 해줍니다.

const express = require("express");
const fileUpload = require('express-fileupload');
const fs = require('fs');

const cors = require = require('cors');
const app = express();

// NOTE:: 크로스 브라우징 주입과 file 객체를 인식 할수 있게 
app.use(cors());
app.use(fileUpload());

const port = ( port ) => {
   if(!port){
      return 4000
   }
   else{
      return port 
   }
}

// NOTE:: 에러처리

app.use((req, res, next) => {
   res.status(404).send('page not find');   
});

app.use((err, req, res, next) => {
   console.log(err.stack);
   res.status(500).send('server error');
})

// NOTE:: 메
app.listen(port(),()=>{
   console.log(`this port is ${port()}`)
})

여기서
use ,get ,post 및 추가 메소드(함수)에 대한 정의는 해당 공식 문서를 통해 확인 할수 있다.

참고
https://expressjs.com/en/4x/api.html#app.all

이제 해당 기능들을 작성해 봅시다.

app.get(``,(req,res) =>{{

   res.send("webcam rest api") 

}}
)

초기 api 접속시 출력될 데이터 호출

app.get(`/webcam/:fileName`,(req,res) =>{{
    // 파일명을 받아 호출 
   const { fileName } = req.params
   	//  __dirname 은 내장객체로 디렉토리 경로를 출력해줌 저장된 파일을 읽기위한 경로
    const filePath = `${__dirname}/video/webcam/${fileName}.mp4`;
	// 파일 사이즈
     const videoSize = fs.statSync(filePath).size;
    // 청크에 사이즈를 1MB 
     const CHUNK_SIZE = 10 ** 6; // 1MB
    // 시작지점
     const start = 0
    // 끝지점
     const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
    // 길이
     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
     const videoStream = fs.createReadStream(filePath, { start, end });
   // 스트림 데이터 할당
     videoStream.pipe(res);
    
}
})

비디오 데이터를 호출할 api

여기서 코드를작성하기전 알아야 할 개념을 봅시다.

Chunk(청크)

직역 하면 덩어라라는 뜻으로 데이터의 덩어리를 의미합니다.

Buffer(버퍼)

임시로 바이너리 형태의 데이터( 2진수 01010101...) 를 저장하기 위한 공간으로 바이너리 데이터를 Chunk 형태로 잘게 쪼개어 가지고 있는 형태입니다.
<Buffer 01 56 35 45 12 > 16진수의 데이터로 Chunk를 출력하지만 실제 가지고 있는값은 2진수로 이루어져있습니다.

Buffering(버퍼링)

Buffer 형태의 데이터를 구성하기 위해선 chunk 데이터가 Buffer 영역에 채워지고 데이터가 채워지면 Buffer를 보내 출력합니다.
이과정중 Chunk 데이터가 Buffer 데이터에 적재되고 있는 과정을 의미하며 동영상 재생중 버퍼링이 걸린다는것도 해당 개념에 해당됩니다.

Stream(스트림)

위에 버퍼링 과정을 연속적으로 실행하는것을 의미합니다.
스트림은 읽기전용과 쓰기전용이 있으며 node.js 의 내장객체인 fs에선 읽기전용 stream 과 쓰기 전용 stream을 제공합니다.

206 state code

참고 https://runebook.dev/ko/docs/http/status/206

app.post(`/webcam`,(req,res) =>{{
	// 전달받은 파일 
   const { file } = req.files;
   // 전달받은 데이터
   const { end } = JSON.parse(req.body.obj).date;
   // 비디오 타입
   const videoType = file.mimetype.replaceAll("video/",".")
   // db를 대체할 json 파일 경로
   const filefetch = `${__dirname}/video/webcam/db.json`;
   // 파일을 읽어들이는 함수
   const readFileFor = () => {
      
      fs.readFile( filefetch , "utf-8" , (err,data) =>{

         if(err){
            console.log(err)
         }
   
         else{
            writeDataFor(data)
         }
   
      });

   }
   // 읽은 파일명과 정보를 db.json에 저장 
   const writeDataFor = ( data ) => {

      let result = !data ? [] :  JSON.parse(data)

      result.push( JSON.parse(req.body.obj) )

      fs.writeFile(filefetch , "" , "utf-8" ,(err) =>{

         if(err){
   
            console.log(err)
   
         }
         else{
   
            fs.appendFileSync(filefetch , JSON.stringify(result) , "utf-8" )
   
         }
   
      })

   }
	// 전달받은 비디오파일을 생성 하여 저장 
   file.mv( `${__dirname}/video/webcam/${end}${videoType}`,
      
      (err) => {
       if (err) {
         return res.status(500).send(err);
       }
       
       else{
        
         fs.readFileSync(`${__dirname}/video/webcam/${end}${videoType}`)
            
         readFileFor()

         return res.status(200)

       }

     }
   );
   
   
}}
)

파일을 저장 하고 영상을 시작한 시간과 끝내는 시간 파일명과 같은 데이터를 json 파일에 저장

여기서 fs readFileSync , readFile와 같이 비동기와 동기를 제공하는 부분은 추가적인 문서를 참고 바랍니다.

참조
https://nodejs.org/api/fs.html

app.get("/webcam_list" , (req,res) => {

   const filefetch = `${__dirname}/video/webcam/db.json`;
      
      fs.readFile( filefetch , "utf-8" , (err,data) =>{

         if(err){
            res.send(err)
            res.status(500)
         }
         
         else{
            res.send(!data ? [] : data )
            res.status(200)
         }
   
      });

   
})

db.json에서 저장한 정보를 호출 하기 위한 api

profile
Code Smell을 향기롭게 하자

0개의 댓글