반응에 대한 도움 요청
나는 단지 시도를 위해 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를 알려주세요.
Reference
이 문제에 관하여(반응에 대한 도움 요청), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/boxser778/seeking-help-with-react-4lc1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)