7/13

JK·2023년 7월 13일
0

월요일부터 오늘까지 하루에 한 번 발표가 있어서 계속 회의와 발표 준비만 한 거 같습니다...
그래도 오늘 발표를 잘 마무리해서 기분이 좋았고 7시에 채용 설명회를 하고 회식해서 공부를 많이 하지 못했습니다. ㅠㅠㅠ

그래도 오늘 알아본 정보들을 정리해보겠습니다

영상 저장 (미디어 파일 처리)

  • 영상 데이터 관리 기술적 챌린지라고 생각한 이유 🔌 영상 데이터는 용량, 전송 대역폭, 소실 등 고려해야 할 것이 많아 전송하는 것이 쉽지 않다. 또한 이를 데이터베이스에 모두 저장하여 관리하기도 쉽지 않다. 그래서 이를 안정적이고 빠르게 활용할 수 있는 방법을 찾아봐야 할 것 같아 이를 기술적 챌린지로 선택했습니다.

MongoDB 에서 영상 데이터 처리

연결방법 → 제일 간단한 방법

🔗 https://jakekwak.gitbook.io/nestjs/techniques/mongo
  1. 설치

    npm install --save @nestjs/mongoose mongoose
  2. app.module.ts : nestjs 애플리케이션에서 MongoDB와의 연결을 설정

    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { MongooseModule } from '@nestjs/mongoose'; //mongoDB 연결
    import { VideoModule } from './video/video.module';
    
    @Module({
      **imports: [MongooseModule.forRoot('mongodb://localhost:27017/test'), VideoModule]**,
      controllers: [AppController],
      providers: [AppService],
    })
    export class AppModule {}

    우선 간단하게 연결만 시도한 상태여서 보안적인 측면에서 env 파일 필요 → config

  3. video.schema.ts : 데이터 모델을 정의

    import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
    import { IsNotEmpty, IsString } from "class-validator";
    import { Document } from 'mongoose';
    
    export type VideoDocument = Video & Document;
    
    @Schema()
    export class Video extends Document {
        @Prop({ required: true })
        @IsString()
        @IsNotEmpty()
        name: string;
    
        @Prop()
        @IsString()
        @IsNotEmpty()
        url: string;
    }
    
    export const VideoSchema = SchemaFactory.createForClass(Video);
  4. video.service.ts : MongoDB와 상호 작용을 위한 서비스를 생성

    import { Injectable } from '@nestjs/common';
    import { Video, VideoDocument } from './schemas/video.schema';
    import { Model } from 'mongoose';
    import { InjectModel } from '@nestjs/mongoose';
    
    @Injectable()
    export class VideoService {
        **constructor(@InjectModel(Video.name) private videoModel: Model<VideoDocument>) { }**
        
        async findAll(): Promise<Video[]> {
            return this.videoModel.find().exec();
        }
        
        async create(video: Video): Promise<Video> {
            const createVideo = new this.videoModel(video);
            return createVideo.save();
        }
    }
  5. video.controller.ts : MongoDB 서비스를 사용

    import { Controller, Get, Post, Body } from '@nestjs/common';
    import { VideoService } from './video.service';
    import { Video } from './schemas/video.schema';
    
    @Controller('video')
    export class VideoController {
        **constructor(private readonly videoService: VideoService) { }**
        
        @Get()
        findAll(): Promise<Video[]> {
            return this.videoService.findAll();
        }
    
        @Post()
        create(@Body() video: Video): Promise<Video> {
            return this.videoService.create(video);
        }
    }
  6. video.module.ts :

    import { Module } from '@nestjs/common';
    import { VideoService } from './video.service';
    import { VideoController } from './video.controller';
    import { MongooseModule } from '@nestjs/mongoose';
    import { Video, VideoSchema } from './schemas/video.schema';
    
    @Module({
      imports: [**MongooseModule.forFeature([{name: Video.name, schema: VideoSchema}])**],
      providers: [VideoService],
      controllers: [VideoController]
    })
    export class VideoModule {}

MongoDB 특성

  • NoSQL : join 필요없음
  • Schema-less : 하나의 collection 내의 document가 각각 다른 schema를 가질 수 있다.
  • document : JSON file → 실제로는 BSON (Binary 형태로 변경된 구조)
    • BSON 사용 이유
      • JSON은 텍스트 기반으로 구문 분석이 매우 느리다.
      • JSON은 공간 효율성과는 거리가 멀다. (데이터베이스 문제)

GridFS → DB에 영상을 저장하는 방법

💡 **BSON 문서 크기 제한인 16MB를 초과하는 파일을 저장하고 검색하기 위한 사양**

https://waterfogsw.tistory.com/5

✅ GridFS 사용시 이점

  1. 파일을 저장하는 구조를 단순화 할 수 있다.
  2. 별도의 파일 저장소를 만들 필요가 없다.
  3. 안정성을 위한 복제, 샤딩등의 기능을 그대로 적용할 수 있어서 분산과 장애복구가 용이하다.
  4. 대용량의 파일을 저장할 때 생기는 파일시스템의 문제(FAT32인지 NTFS인지의 문제)가 발생하지 않는다.

[참고][실제 구현 코드](https://velog.io/@dpekfa144/%EC%8B%A4%EC%A0%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%9D%BC%EC%A7%80-27%EC%9D%BC%EC%B0%A8-) - 단 몽고DB 프리티어에서는 500MB이상 불가

간단하게 GridFS를 이용하여 영상 저장

from pymongo import MongoClient
from gridfs import GridFS

# mongoDB는 27017 포트사용
client = MongoClient('localhost', 27017)

# test라는 이름의 DB를 만든다.
db = client.test

# GridFS 인스턴스 생성
fs = GridFS(db, collection='test_gridfs_collection')

# 영상 파일 열기
with open('/Users/chosoobeen/Desktop/Jungle/video_test/video.webm', 'rb') as video_file:
    # 영상 데이터를 GridFS에 저장
    video_id = fs.put(video_file, filename='/Users/chosoobeen/Desktop/Jungle/video_test/video.webm')

print('영상이 MongoDB에 저장되었습니다. ID:', video_id)

서버에서 압축을 할지, 클라이언트에서 압축할지? 서버 환경에 따라 다를듯

압축을 해제하는 것은 클라이언트에서 하는게 나을지도..?
→ 클라이언트 측에서 병렬 처리와 더 빠른 하드웨어 성능을 활용할 수 있다.

또는 aws S3에 저장하고 저장된 URL? 또는 위치? 를 mongoDB에 저장

S3 → AWS 온라인 스토리지에 저장하는 방법 ✅

🔗 https://velog.io/@jinseoit/AWS-S3-bucket [https://velog.io/@leeeeeyeon/AWS-S3로-파일-서버를-만들어보자](https://velog.io/@leeeeeyeon/AWS-S3%EB%A1%9C-%ED%8C%8C%EC%9D%BC-%EC%84%9C%EB%B2%84%EB%A5%BC-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EC%9E%90) https://campkim.tistory.com/66

multer 미들웨어

1. 클라이언트에서 직접 S3에 업로드 하는 방식

🔷 장점

  • 서버 부하를 줄일 수 있다
  • 클라이언트가 직접 필요한 데이터를 관리하여 지연시간 감소, 응답성 향상

‼️ 고려해야 할 사항

  • S3에 접근하기 위한 인증 정보를 클라이언트에 저장하면 위험
    • server에 인증 정보를 두고 요청하는 방식을 생각함
  • 클라이언트가 직접 S3에 접근하므로 제어하기 어렵고 서버에서 무결성 검사, 캐싱, 효율적인 데이터 전송을 제공하기 어렵다.

웹캠, 화면 녹화

MediaStream Redcording API

웹 브라우저에서 웹 카메라, 마이크, 화면 등의 미디어 스트림을 녹화하는 기능을 제공하는 API

미디어스트림을 실시간으로 녹화하거나 녹화된 미디어 스트림을 재생할 수 있다.

  1. 웹캠 실시간 확인/녹화/다운로드
  • 구현프로세스
    1. MediaStream Recording API로, 해당 stream을 가져온다
    2. MediaStream을 매개변수로, MediaRecorder 생성자를 호출한다
    3. MediaRecorder.ondataavailable 이벤트가 호출될 때마다 전달 받는 영상 데이터를 배열에 쌓는다
    4. 녹화를 중지하면, 모인 영상 데이터로 Blob을 생성하는 핸들러를 MediaRecorder.onstop 이벤트에 등록한다 / MediaRecorder.start() 를 호출해 녹화 시작 / MediaRecorder.stop() 을 호출해 녹화를 중지한다
    5. 4번에서 Blob으로 생성한 URL 데이터를 ajax를 이용해 서버로 POST 한다
  • 구현기능
    • 웹캠에 찍히는 화면을 실시간으로 확인 → 연습모드
    • 웹캠 찍히는 화면을 녹화 (녹화 시작, 녹화 종료) → 연습/실전 모드
    • 녹화된 영상 미리보기 → 추가기능
    • 녹화된 영상 다운로드 → 마이페이지

나만의 설명:

Media Stream을 Recording 하는 API로 MediaRecorder객체 하나로 구성되어 있다.

즉, MediaStream객체를 통해 입력 받는 소리, 영상, 화면 등을 MediaRecorder객체로 녹음 및 녹화하는 API이다.

Blob(Binary Large Obeject)은 미가공 데이터를 처리하거나 간접 참조하는 객체

  1. 화면 녹화/다운로드
  2. 웹캠(발표자) + 화면(발표자료) 합성해서 어떻게 녹화할 것인가?
  • 스트림 병합
profile
^^

0개의 댓글

관련 채용 정보