개발노트

54. [Flutter] Firebase functions 에 ffmpeg 패키지로 영상 썸네일 저장하기 본문

앱 개발/Flutter

54. [Flutter] Firebase functions 에 ffmpeg 패키지로 영상 썸네일 저장하기

mroh1226 2024. 1. 9. 17:57
반응형

FirebaseCloud Functions에서 기본적으로 제공되는 ffmpeg 패키지는 동영상, 이미지, 오디오 처리를 도와주는 패키지로 각종 명령어를 통해 다양한 작업이 가능합니다.

 

FFmpeg이란?

FFmpeg: FFmpeg은 무료 오픈 소스 소프트웨어 패키지로, 오디오와 비디오 데이터의 녹화, 변환, 편집, 스트리밍 등 다양한 멀티미디어 작업을 수행하는 데 사용되는 강력한 도구입니다.

주요 기능

  1. 다양한 형식 지원:
    • 오디오와 비디오의 다양한 코덱과 형식을 지원하여 사용자가 쉽게 변환하거나 편집할 수 있습니다.
  2. 코덱 및 필터:
    • 다양한 코덱을 활용하여 미디어를 인코딩하고 디코딩할 수 있습니다. 필터를 사용하여 화질 조절, 자막 추가 등 다양한 조작이 가능합니다.
  3. 라이브 스트리밍:
    • 다양한 프로토콜을 지원하여 라이브 비디오 스트리밍을 가능케 하며, 실시간 업데이트에 활용할 수 있습니다.
  4. 프로파일 및 품질 제어:
    • 사용자는 비트레이트, 해상도, 색상 프로파일 등을 조절하여 출력 미디어의 프로파일과 품질을 높일 수 있습니다.
  5. 오픈 소스:
    • FFmpeg은 오픈 소스 프로젝트로, 자유롭게 사용하고 수정할 수 있습니다. 이는 다양한 플랫폼에서 커뮤니티에 의해 계속 발전하고 있습니다.

사용 예시

  1. 동영상 변환:
    • 다양한 동영상 형식 간의 변환을 수행하여 원하는 형식으로 동영상을 변경할 수 있습니다.
  2. 오디오 추출:
    • 동영상에서 오디오를 추출하거나, 오디오 파일을 다양한 형식으로 변환할 수 있습니다.
  3. 화면 녹화:
    • 화면 녹화를 수행하고 이를 다양한 형식으로 저장할 수 있습니다.
  4. 라이브 스트리밍 서비스:
    • FFmpeg을 사용하여 라이브 비디오를 스트리밍하고, 웹사이트나 앱에서 실시간으로 제공할 수 있습니다.

 

- ffmpeg 사이트: https://ffmpeg.org/

 

FFmpeg

Converting video and audio has never been so easy. $ ffmpeg -i input.mp4 output.avi     News January 3rd, 2024, native VVC decoder The libavcodec library now contains a native VVC (Versatile Video Coding) decoder, supporting a large subset of the codec's

ffmpeg.org

 

- 자주 사용되는 ffmpeg 명령어 모음: https://ostechnix.com/20-ffmpeg-commands-beginners/

 


패키지 설치.

먼저, 프로젝트 functions 폴더로 이동한 뒤 npm i child-process-promise 명령어로 패키지를 설치합니다.

functionsffmpeg 패키지를 기본으로 제공하기 때문에 이는 따로 설치하지않습니다.

*child-process-promise : 코드가 실행되는 서버에 프로세스를 실행시킬 수 있도록해주는 패키지

npm i child-process-promise

소스예시.

- 구현 목표: 업로드된 영상의 썸네일을 ffmpeg로 만들고 Storage에 저장 후, URL을 생성하여 firestore 컬랙션에 URL을 업데이트하는 functions 을 만들어보겠습니다.

index.ts (function/src/index.ts)
//firebase-functions: Firebase Cloud Functions를 사용하기 위한 모듈입니다.
import * as functions from "firebase-functions";
//firebase-admin: Firebase 관리 기능을 사용하기 위한 모듈입니다.
import * as admin from "firebase-admin";

admin.initializeApp();

export const onVideoCreated = functions.firestore
  .document("videos/{videoId}")
  //onCreate 이벤트 리스너는 두 개의 매개변수를 받습니다.
  //snapshot: 이벤트가 발생한 문서에 대한 스냅샷입니다.
  //context: 함수의 실행 컨텍스트에 대한 정보를 포함하는 객체입니다.
  .onCreate(async (snapshot, context) => {
    //spawn으로 npm 명령어 실행
    const spawn = require("child-process-promise").spawn;
    const video = snapshot.data();
    //ffmpeg에 파라미터를 전달함
    await spawn("ffmpeg", [
      "-i",
      video.fileUrl, //업로드 하는 영상을 가져옴
      "-ss",
      "00:00:01.000", //영상의 1초 뒤로 이동
      "-vframes",
      "1", //1프레임을 가져옴
      "-vf", // 화질을 낮춤
      "scale=150:-1", //가로 150 세로 -1(-1: 세로비율 알아서 맞춤)
      `/tmp/${snapshot.id}.jpg`, //이미지를 처리하고 이 경로로 저장함
    ]);
    //admin으로 스토리지에 접근하여 ffmpeg에서 작업된 이미지를 스토리지에 저장함
    const storage = admin.storage();
    const [file, _] = await storage.bucket().upload(`/tmp/${snapshot.id}.jpg`, {
      destination: `thumbnails/${snapshot.id}.jpg`,
    });
    //file을 공개화시킴
    await file.makePublic();
    await snapshot.ref.update({ thumbnailUrl: file.publicUrl() });
    //admin으로 firesotre 접근
    const db = admin.firestore();
    //users 컬랙션 안에 videos 컬랙션, document 추가하기
    await db
      .collection("users")
      .doc(video.creatorUid)
      .collection("videos")
      .doc(snapshot.id)
      .set({
        thumbnailUrl: file.publicUrl(),
        videoId: snapshot.id,
      });
  });

 

 

배포하기.

프로젝트 functions 폴더에 들어가서 firebase deploy --only functions 명령어로 functions만 배포하기

배포완료


동작하는 모습.

1. 동영상을 촬영하고 Storagevideos에 파일을 업로드합니다.(User 로그인된 상태)

2. Firestorevideos 컬랙션에 업로드한 영상정보가 포함된 document가 생성됩니다.

3. 이제 functions에 배포된 onVideoCreated() 함수가 동작하며, ffmpeg 로 썸네일 이미지를 만들어냅니다.

4. 만들어낸 썸네일 이미지를 Storage에 저장합니다.(URL 생성)

5. 만들어진 썸네일 URL을 videos와 users>videos컬랙션에 update합니다.

 

Storage (thumbnails 저장됨, URL 생성됨)

ffmpeg로 생성된 thumbnail 이미지가 Storage에 저장된 모습

firestore 의 videos 컬랙션 최종 모습

firestore videos 컬랙션에 thumbnailUrl이 functions의 onVideoCreated() 함수에 의해 update 된 모습

 

firestore의 users 컬랙션 최종 모습(내부에 videos 컬랙션 생성됨)

users 안에 썸네일과 비디오Id를 갖는 videos 컬랙션이 생김

 

ffmpeg 로 생성된 썸네일 이미지, 이미지가 저장된 function 서버 URL로 접속했을 때 모습

thumbnailUrl 로 접속하면 이미지가 나옵니다.

 

반응형
Comments