DM Log

[#1 영상 파일 재생] -1. 화면개발- [frontend] Dummy Data를 통한 재생 화면 구성 본문

SUB-PJT/영상 파일 재생 PJT

[#1 영상 파일 재생] -1. 화면개발- [frontend] Dummy Data를 통한 재생 화면 구성

Dev. Dong 2025. 3. 24. 21:50

[frontend] Dummy Data를 통한 재생 화면 구성


개요

영상 파일 재생 화면 개발 프로젝트의 Dummy 영상 데이터를 제작하고 화면을 구성하고 컴포넌트를 개발을 진행하였다.


진행 내용

  1. public에 영상 파일 저장하고 해당 경로를 저장하는 json 파일 생성 (더미 데이터 생성)
  2. VideoView 화면(VideoTable & VideoPlayer)를 제작
  3. VideoTable의 파일명 클릭 시 VideoPlayer에 public에 있는 해당 영상 파일 재생 기능

VideoView

  • VideoTable와 VideoPlayer를 보여주는 화면
  • 선택된 비디오의 상태 값과 선택 값을 관리하기 위해 제작
import { useEffect, useState } from 'react'
import { dummyVideos, VideoFile } from '../data/dummyVideos';
import VideoTable from "../components/VideoTable";
import VideoPlayer from '../components/VideoPlayer';

export default function VideoView() {
  const [videos, setVideos] = useState<VideoFile[]> ([]);
  const  [selectedPath, setSelectedPath] = useState<string| null> (null);
  useEffect(() => {
    setVideos(dummyVideos)
  }, [])
  return (
    <div>
      <div>
        <h2>Video List</h2>
        <VideoTable videos={videos} onSelect={setSelectedPath}/>
      </div>
      <div>
        <h2>Video Player</h2>
        <VideoPlayer path={selectedPath}/>
      </div>
    </div>
  )
}

VideoTable

    • 영상 파일의 이름을 띄우고 선택 가능한 컴포넌트
/** @jsxImportSource @emotion/react */
// import { css } from '@emotion/react';
import { VideoFile } from '../data/dummyVideos';

type Props = {
  videos: VideoFile[]
  onSelect: (path:string) => void
}
export default function VideoTable({videos, onSelect}:Props) {

  const selectedPathClick = (video: VideoFile) => {
    onSelect(video.path)
    console.log(`${video.path} 클릭중`)
  }
  return (
    <table>
      <thead>
        <tr>
          <th>파일 경로</th>
          </tr>
      </thead>
      <tbody>
        {videos.map((video, idx) => (
          <tr key={`${video.path}-${idx}`} onClick={() => selectedPathClick(video)}>
            <td>{video.path}</td>
          </tr>
        ))}
      </tbody>
    </table>
  )
}

VideoPlayer

  •  선택된 영상을 재생하는 컴포넌트
import { useEffect, useRef } from "react";

type Props = {
  path:string | null;
}
export default function VideoPlayer({ path }: Props) {
  const videoRef = useRef<HTMLVideoElement | null>(null);

  useEffect(() => {
    if (videoRef.current && path) {
      const video = videoRef.current;

      video.pause();
      video.load();
      video.play().catch((err) => {
        console.warn('재생 실패', err);
      })
    }
  }, [path])

  if (!path) return <div>👈 영상을 선택해주세요.</div>;
  return (
    <video
      ref={videoRef}
      controls
      muted
      autoPlay
    >
      <source src={`/video/${path}`} type="video/webm" />
      브라우저가 video 태그를 지원하지 않습니다.
    </video>
  );
}

화면

  • 영상 재생 만 가능한 허접한 화면,,,