반응에 대한 도움 요청

10602 단어 expressnodereact
안녕하세요 , 제 프로젝트 에 약간 의 문제 가 있습니다 .
나는 단지 시도를 위해 youtube 클론을 만들려고 합니다.

나는 비디오를 업로드할 때 문제에 부딪쳤고 클라이언트 측에 실제로 표시되지 않는 썸네일을 생성합니다. 나는 반응하는 공급자와 관련이 있다고 믿습니다.
모든 곳을 검색했지만 내 문제에 대한 답을 찾을 수 없었기 때문에 정말 도움을 받고 싶습니다.

https://giphy.com/gifs/fJA5VRltmMKl0OuIDZ

이것은 개발자 도구에서 발생하는 오류입니다.
:5000/uploads/thumbnails/thumbnail-1656867800686_1575467783672_Space%20-%2021542.png:1 GET http://localhost:5000/uploads/thumbnails/thumbnail-1656867800686_1575467783672_Space%20-%2021542.png net::ERR_CONNECTION_REFUSED

고객 입장에서:

import React, { useState } from 'react';
import { Typography, Button, Form, message, Input } from 'antd';
import Dropzone from 'react-dropzone';
import Axios from 'axios';
import {getCurrentUser} from "../../services/userService"

const apiUrl = process.env.REACT_APP_API_URL;
const { TextArea } = Input;
const { Title } = Typography;

const PrivateOptions = [
    { value: 0, label: "Private" },
    { value: 1, label: "Public" }
]

const CategoryOptions = [
    { value: 0, label: "Film & Animation" },
    { value: 1, label: "Autos & Vehicles" },
    { value: 2, label: "Music" },
    { value: 3, label: "Pets & Animals" },
    { value: 4, label: "Sports" }
]

function VideoUploadPage(props) {

    const user = getCurrentUser();

    const [VideoTitle, setVideoTitle] = useState("")
    const [Description, setDescription] = useState("")
    const [Private, setPrivate] = useState(0)
    const [Category, setCategory] = useState("Film & Animation")
    const [FilePath, setFilePath] = useState("")
    const [Duration, setDuration] = useState("")
    const [ThumbnailPath, setThumbnailPath] = useState("")

    const onTitleChange = (e) => {
        setVideoTitle(e.currentTarget.value)
    }

    const onDescriptionChange = (e) => {
        setDescription(e.currentTarget.value)
    }

    const onPrivateChange = (e) => {
        setPrivate(e.currentTarget.value)
    }

    const onCategoryChange = (e) => {
        setCategory(e.currentTarget.value)
    }

    const onDropFuc = (files) => {
        let formData = new FormData();
        const config = {
            header: {'content-type': 'multipart/form-data'}
        }

        formData.append("file", files[0])

        Axios.post(`${apiUrl}/videos/uploadfiles`, formData, config)
            .then(response => {
                if(response.data.success){

                    let variable = {
                        url: response.data.url,
                        fileName: response.data.fileName
                    }

                    setFilePath(response.data.url)

                    Axios.post(`${apiUrl}/videos/thumbnail`, variable)
                        .then(response => {
                            if(response.data.success){
                                setDuration(response.data.fileDuration)
                                setThumbnailPath(response.data.url)
                            } else {
                                alert("ERROR: Failed to display a thumbnail.")
                            }
                        })

                } else {
                    alert('ERROR: Failed to upload a video');
                }
            })
    }

    const onSubmit = (e) => {
        e.preventDefault();

        const variables = {
            writer: user._id,
            title: VideoTitle,
            description: Description,
            privacy: Private,
            filePath: FilePath,
            category: Category,
            duration: Duration,
            thumbnail: ThumbnailPath
        }

        Axios.post(`${apiUrl}/videos/uploadvideo`, variables)
            .then(response => {
                if(response.data.success){
                    message.success('Successfully uploaded the video!');
                    // setTimeout(() => {
                    //     props.history.push('/') // After 2 seconds of video upload, move to the Landingpage.
                    // }, 2000);
                } else {
                    alert("ERROR: Failed to upload the video.")
                }
            })
        }

    return (
        <div style={{ maxWidth: '700px', margin: '2rem auto'}}>
            <div style={{ textAlign: 'center', marginBottom: '2rem' }}>
                <Title level={2}> Upload Video </Title>
            </div>

            <Form onSubmit={onSubmit}>
                <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                    <Dropzone
                        onDrop = {onDropFuc}
                        multiple = {false}
                        maxsize = {100000000}
                    >
                        {({getRootProps, getInputProps}) => (
                            <div style={{ width: '300px', height: '240px', border: '1px solid lightgray', 
                            display: 'flex', alignItems: 'center', justifyContent: 'center' }} {...getRootProps()}>
                                <input {...getInputProps()} />
                            </div>
                        )}
                    </Dropzone>

                    {ThumbnailPath &&
                        <div>
                            <img src={`http://localhost:5000/${ThumbnailPath}`} alt="thumbnail" />      
                        </div>
                    }  
                </div>

                <br/><br/>

                <label>Title</label>
                <Input
                    onChange = {onTitleChange}
                    value = {VideoTitle}
                />

                <br/><br/>

                <label>Description</label>
                <TextArea
                    onChange = {onDescriptionChange}
                    value = {Description}
                />

                <br/><br/>

                <select onChange={onPrivateChange}> 
                    {PrivateOptions.map((item, index) => (
                        <option key={index} value={item.value}>{item.label}</option>
                    ))}
                </select>

                <br/><br/>

                <select onChange={onCategoryChange}> 
                    {CategoryOptions.map((item, index) => (
                        <option key={index} value={item.value}>{item.label}</option>
                    ))}
                </select>

                <br/><br/>

                <Button type='primary' size='large' onClick={onSubmit}>
                    Upload
                </Button>
            </Form>
        </div>
    );
}

export default VideoUploadPage


서버 측:

const express = require('express');
const router = express.Router();
const multer = require("multer");
var ffmpeg = require("fluent-ffmpeg");

const { Video } = require("../vi/videoModel");

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('ERROR: Only mp4 file 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.file.filename })

    })
});

router.post('/getVideoDetail', (req, res) => {

    Video.findOne({ "id" : req.body.videoId })
    .populate('writer')
    .exec((err, videoDetail) => {
        if(err) return res.status(400).send(err);
        res.status(200).json({ success: true, videoDetail })
    })
});

router.post('/uploadvideo', (req, res) => {
    const video = new Video(req.body)

    video.save((err, doc) => {
        if(err) return res.json({ success: false, err })
        res.status(200).json({ success: true })
    })
})

router.get('/getVideos', (req, res) => {
    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({
            count: 1,
            folder: 'uploads/thumbnails',
            size:'320x240',
            filename:'thumbnail-%b.png'
        });

});

module.exports = router;



필요한 경우 기꺼이 전체 프로젝트를 보내 드리겠습니다. 도우미를 위해 thnx를 알려주세요.

좋은 웹페이지 즐겨찾기