VideoPlayer.jsx:34 GET http://localhost:3001/public/test/output.m3u8 404(未找到)

问题描述 投票:0回答:1

我想将视频流式传输到网站,以便用户不必等待整个视频加载,但我遇到了一个错误:Video Player.jsx:34 GET http://localhost:3001/public /test/output.m3u8(未找到) 我做的一切都是对的,但我无法回避这个问题。请帮忙,我的代码应该将视频分成几部分,然后必须播放它。

videoplayer.jsx

import React, { useEffect, useRef, useState } from 'react';
import Hls from 'hls.js';

const VideoPlayer = () => {
    const videoRef = useRef(null);
    const [videoUrl, setVideoUrl] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const fetchVideo = async () => {
            try {
                const response = await fetch('http://localhost:3001/');
                if (!response.ok) {
                    throw new Error(`Сервер вернул статус: ${response.status}`);
                }
                // Установите URL для HLS
                setVideoUrl('http://localhost:3001/public/test/output.m3u8');

            } catch (error) {
                console.error('Ошибка при получении видео:', error);
            } finally {
                setLoading(false);
            }
        };

        fetchVideo();
    }, []);

    // Воспроизведение HLS
    useEffect(() => {
        if (videoUrl && videoRef.current) {
            if (Hls.isSupported()) {
                const hls = new Hls();
                hls.loadSource(videoUrl);
                hls.attachMedia(videoRef.current);
                hls.on(Hls.Events.MANIFEST_PARSED, () => {
                    videoRef.current.play();
                });
            } else if (videoRef.current.canPlayType('application/vnd.apple.mpegurl')) {
                videoRef.current.src = videoUrl;
                videoRef.current.addEventListener('loadedmetadata', () => {
                    videoRef.current.play();
                });
            }
        }
    }, [videoUrl]);

    return (
        <div>
            {loading ? <p>Загрузка видео...</p> : (
                <video ref={videoRef} controls width="640" height="360"></video>
            )}
        </div>
    );
};

export default VideoPlayer;

转换后的.js

import express from 'express';
import cors from 'cors';
import { spawn } from 'child_process';
import fs from 'fs';
import path from 'path';

const app = express();
const PORT = 3001;

app.use(cors());
app.get('/test-file', (req, res) => {
    const testFilePath = path.join('C:/Users/fomic/vite-project/public/test/test.txt');
    
    fs.readFile(testFilePath, 'utf8', (err, data) => {
        if (err) {
            console.error('Ошибка при чтении файла:', err);
            return res.status(500).send('Ошибка при чтении файла.');
        }
        res.send(data);
    });
});

app.get('/', (req, res) => {
    const inputVideo = path.join('C:/Users/fomic/vite-project/public/videoplayback.mp4');
    const outputPlaylist = path.join('C:/Users/fomic/vite-project/public/test/output.m3u8');

    console.log('Проверка входного файла:', inputVideo);
    if (!fs.existsSync(inputVideo)) {
        console.error('Ошибка: входной файл не найден.');
        return res.status(404).send('Входной файл не найден.');
    }
    
    // Проверка существования входного файла
    console.log('Проверка входного файла:', inputVideo);
    if (!fs.existsSync(inputVideo)) {
        console.error('Ошибка: входной файл не найден.');
        return res.status(404).send('Входной файл не найден.');
    }

    // Проверка существования выходной директории
    const outputDir = path.dirname(outputPlaylist);
    console.log('Проверка директории для выходных файлов:', outputDir);
    if (!fs.existsSync(outputDir)) {
        console.log('Директория не найдена. Создаю новую директорию...');
        fs.mkdirSync(outputDir, { recursive: true });
    }

    console.log('Запуск FFmpeg для конвертации...');
    const ffmpegProcess = spawn('ffmpeg', [
        '-i', inputVideo,
        '-c', 'copy',  // Исправлено здесь
        '-start_number', '0',
        '-hls_time', '10',
        '-hls_list_size', '0',
        '-f', 'hls',
        outputPlaylist
    ]);

    ffmpegProcess.stdout.on('data', (data) => {
        console.log(`stdout: ${data}`);
    });

    ffmpegProcess.stderr.on('data', (data) => {
        console.error(`stderr: ${data.toString()}`);
    });

    ffmpegProcess.on('close', (code) => {
        if (code === 0) {
            res.send('Конвертация завершена!');
        } else {
            console.error(`Ошибка при выполнении FFmpeg, код: ${code}`);
            res.status(500).send(`Ошибка при конвертации видео, код: ${code}`);
        }
    });
});

// Запуск сервера
app.listen(PORT, () => {
    console.log(`Сервер запущен на http://localhost:${PORT}`);
});
  

app.jsx

import { useState } from 'react'
import Release from './components/Release/Release'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
import Header from './components/Header/Header'
import Podcaster from './components/Podcaster/Podcaster'
import TabsSection from './components/TabsSection/TabsSection'
import LentaSection from './components/LentaSection/LentaSection'
import SubscribesSection from './components/SubscribesSection/SubscribesSection'
import PlayListSection from './components/PlayListSection/PlayListSection'
import { Registration } from './components/Forms/Registration'
import { Auth } from './components/Forms/Aurh'
import { BrowserRouter as Router, Route,  Routes } from 'react-router-dom'; 

function App() {
  const [count, setCount] = useState(0)


  return (
    <>
    <Router> 
            
                <Header/>  

                <Routes>
                <Route path="/auth" element={<Auth />} />
                <Route path="/release" element={<Release />} />
                <Route path="/podcaster" element={<Podcaster />} />
            </Routes>

                  
            
        </Router> 
    
    </>
  )
}

export default App
javascript reactjs
1个回答
-1
投票

确保您的 Express 服务器配置为提供静态文件 在您的服务器代码中添加此行

app.use('/public',express.static(path.join(__dirname,'public')));

这将允许您的服务器从公共目录正确提供 .m3u8 和视频文件

确保您的 VideoPlayer.jsx 正在获取正确的视频 URL

setVideoUrl('http://localhost:3001/public/test/output.m3u8');

此 URL 应与服务器提供 .m3u8 文件的路径匹配

© www.soinside.com 2019 - 2024. All rights reserved.