랜딩페이지 비디오 나타내기
본문 바로가기
WEB

랜딩페이지 비디오 나타내기

by KyeongMin 2021. 3. 5.
728x90
반응형

비디오 Template 만들고

 

몽고DB에서 데이터 가져오고

 

가져온 비디오 데이터 스크린에 출력 Use map() methods

 

랜딩 페이지에서 우선 이거 만들고 

import React ,{useEffectfrom 'react'

 

    useEffect(() => {
     Axios.get('/api/video/getVideos')
     .then(respones=>{
         if(respones.data.success){

         }else{
             alert('비디오 가져오기를 실패 했습니다.')
         }
     })
    }, [])

라우터 생성을 위해 server의 video.js 부분으로 갑니다. 

routes/video.js 부분에

router.post('/getVideos',(req,res)=>{
    //비디오를 DB에서 가져와서 클라이언트에 보낸다. 
    Video.find()
    .populate('writer') //이populate를 써야 모든 정보를 가져온다. 
    .exec((err,videos)=>{
        if(err) return res.status(400).send(err);
        res.status(200).json({success: true, videos})
    })
})

이렇게뜨면 정상

 

혹시나 에러가 생길 수 있으니

const express = require('express');
const router = express.Router();
const { Video } = require("../models/Video");
const path = require("path");
const { auth } = require("../middleware/auth");
const multer = require("multer");
var ffmpeg = require("fluent-ffmpeg");

//storage multer config
let storage = multer.diskStorage({
    destination : (req,file,cb)=>{
        cb(null,"uploads/");
    },
    filename: (req, file, cb)=>{
        cb(null,'${Date.now()}_$file.originalname}');
    },
    fileFilter: (req,file,cb)=>{
        const ext = path.extname(file.originalname)
        if(ext!='.mp4'){
            return cb(res.status(400).end('only jpg, png, mp4 is allowed'),false);
        }
        cb(null,true)
    }
});
const upload = multer({storage: storage}).single("file");
//=================================
//             Video
//=================================
router.post('/uploadfiles',(req,res)=>{
    //비디오를 서버에 저장한다. 
    upload(req,res,err=>{
        if(err){
            return res.json({success: false, err})
        }
        return res.json({success: true,url: res.req.file.path, fileName: res.req.filename })
    })
})
router.post('/uploadVideo',(req,res)=>{
    //비디오를 정보를 저장한다. 
    const video=new Video(req.body)
    video.save((err,video)=>{
        if(err) return res.json({success: false, err})
        res.status(200).json({success: true})
    })
})
router.get("/getVideos", (req, res) => {
    //비디오를 DB에서 가져와서 클라이언트에 보낸다.
  
    Video.find()
      .populate('writer')
      .exec((err, videos) => {
        if (err) return res.status(400).send(err);
        res.status(200).json({ success: true, videos });
      })
  })
  
router.post('/thumbnail',(req,res)=>{
        //썸네일 생성 하고 비디오 러닝타임도 가져오기
        let filePath ="";
        let fileDuration ="";
        //비디오 정보 가져오기 
        ffmpeg.ffprobe(req.body.url, function(err, metadata){
            console.dir(metadata);
            console.log(metadata.format.duration);
            fileDuration = metadata.format.duration;
        });
    
        //썸네일 생성
        ffmpeg(req.body.url)
        .on('filenames', function (filenames) {//비디오 썸네일 파일 이름 생성
            console.log('Will generate ' + filenames.join(', '))
            console.log(filenames)
         filePath = "uploads/thumbnails/" + filenames[0];
        })
        .on('end', function () {//썸네일 생성한 후에 무엇을 할것 인지 
            console.log('Screenshots taken');
            return res.json({ success: true, url: filePath, fileDuration: fileDuration});
        })
        .on('error',function(err){
            console.error(err);
            return res.json({success: false, err});
        })
        .screenshots({
            // Will take screens at 20%, 40%, 60% and 80% of the video
            count: 3,
            folder: 'uploads/thumbnails',//이렇게 되어있으니 저번에 uploads폴더 안에 thumbnails폴더 생성
            size:'320x240',
            // %b input basename ( filename w/o extension )
            filename:'thumbnail-%b.png'
        })
})

module.exports = router;

참고하시고,

 

 

랜딩 페이지로 돌아가서

import React ,{useEffect,useStatefrom 'react'

 

선언

    const [VideosEtVideo] = useState([])

    useEffect(() => {
     Axios.get('/api/video/getVideos')
     .then(respones=>{
         if(respones.data.success){
            console.log(respones.data)
            setVideo(respones.data.Video)
         }else{
             alert('비디오 가져오기를 실패 했습니다.')
         }
     })
    }, [])

마무리 해주고

import moment from 'moment'

선언하고

 

import { Card,Icon,Avatar,Col,Typography,Row } from 'antd';
import Axios from 'axios';
import React ,{useEffect,useState} from 'react'
import moment from 'moment'
const { Title } = Typography
const { Meta}  = Card;

function LandingPage() {
    const [Video, setVideo] = useState([])
    useEffect(() => {
     Axios.get('/api/video/getVideos')
     .then(respones=>{
         if(respones.data.success){
            setVideo(respones.data.videos)
         }else{
             alert('비디오 가져오기를 실패 했습니다.')
         }
     })
    }, [])
    const renderCards =Video.map((video, index)=>{
        var minutes= Math.floor(video.duration/60);
        var seconds = Math.floor((video.duration-(minutes*60)));
                     {/*lg 6이면 4개의 화면 //md 8이니까 줄어들었을때 3개의 화면*/}
        return <Col key={index} lg={6} md={8} xs={24}>
            <a href = {`/video/post/${video._id}`}>
            <div style={{position: 'relative'}}>
                <img style={{width: '100%'}} src={`http://localhost:5000/${video.thumbnail}`} alt="thumbnail"/>
                <div className="duration">
                    <span>{minutes} : {seconds}</span>
                </div>
            </div>
        </a>
        <br/>
        <Meta
        avatar={
            <Avatar src={video.writer.image}/>
        }
        title ={Video.title}
        description=""                
        />
        <span>{video.writer.name}</span><br/>
        <span style={{marginLeft:'3rem'}}>{video.views} views</span> - <span>{moment(video.createdAt).format("MMM  Do YY")}</span>
        </Col>  
       
    }) 

    return (
       <div style={{width: '85%', margin: '3rem auto'}}>
           <Title level={2}>Recommended</Title>
           <hr/>
           <Row gutter={[32,16]}>
                {renderCards}
           </Row>
       </div>
    )
}

export default LandingPage

최종 소스이고

hoc / index.css 부분으로 가서

 

 

.duration{
  bottom : 0;
  right : 0;
  position: absolute;
  margin: 4px;
  color: #fff;
  background-color: rgba(17,17,17,0.8);
  opacity: 0.8;
  padding: 2px 4px;
  border-radius: 2px;
  letter-spacing: 0.5px;
  font-size: 12px;
  font-weight: 500;
  line-height: 12px;
}

 

추가합니다. 

 

이렇게

 

이렇게 크기에 따라 달라지는거죠.

728x90
반응형

댓글