Я работаю над школьным проектом, создаю какой-то стриминговый сайт. Предполагается, что я смогу транслировать фильм с помощью WebTorrent асинхронно. Я использую NodeJS, React и Mongo. У меня есть своего рода «домашняя страница», на которой отображаются миниатюры фильмов, и когда я нажимаю на нее, я перенаправляюсь на страницу потоковой передачи с идентификатором торрента в URL-адресе. При этом сервер может собирать данные для этого фильма из базы данных. Вот код страницы потоковой передачи:
import React, { useEffect, useState, useRef } from 'react';
import axios from 'axios';
import { useParams } from 'react-router-dom';
function TorrentStream() {
const { id } = useParams();
const videoRef = useRef(null);
const [movie, setMovie] = useState(null);
useEffect(() => {
const fetchMovieDetails = async () => {
try {
const response = await axios.get(`https://localhost:3002/api/movies/${id}`);
setMovie(response.data);
console.info()
} catch (error) {
console.error('Error fetching movie details:', error);
}
};
fetchMovieDetails();
}, [id]);
const handleStreamVideo = async () => {
try {
const response = await axios.get(`https://localhost:3002/api/movies/stream/${id}`, {
headers: {
'Range': 'bytes=0-'
},
responseType: 'blob'
});
const blobUrl = URL.createObjectURL(response.data);
if (videoRef.current) {
videoRef.current.src = blobUrl;
videoRef.current.load();
videoRef.current.play();
}
} catch (error) {
console.error('Error fetching video:', error);
}
};
У меня есть небольшая кнопка потока, которая вызывает handleStreamVideo при нажатии. Это вызывает вызов этой функции API:
export const streamMovie = async (req, res) => {
const { id } = req.params;
try {
const movie = await Movie.findById(id);
if (!movie) {
console.error('Movie not found');
return res.status(404).json({ message: 'Movie not found' });
}
const magnetURI = movie.magnet_link;
let existingTorrent = client.get(magnetURI);
console.info('magnetURI:', magnetURI);
console.info('existingTorrent:', existingTorrent);
if (existingTorrent) {
handleStream(existingTorrent, req, res);
} else {
client.add(magnetURI, { path: movie.storage_path }, torrent => {
torrent.on('ready', () => handleStream(torrent, req, res));
torrent.on('error', error => console.error('Error adding torrent:', error));
});
}
} catch (err) {
console.error('Error fetching movie:', err);
res.status(500).json({ message: 'Error fetching movie', err });
}
};
и, как вы можете видеть, это вызывает последнюю функцию:
const handleStream = async (torrent, req, res) => {
try {
await torrent.ready;
const file = torrent.files.find(file => file.name.endsWith('.mp4'));
if (!file) {
console.error('No suitable video file found in the torrent');
return res.status(404).json({ message: 'No suitable video file found in the torrent' });
}
const range = req.headers.range;
if (!range) {
console.error('Range header is required');
return res.status(400).send("Requires Range header");
}
const positions = range.replace(/bytes=/, "").split("-");
const start = parseInt(positions[0], 10);
const total = file.length;
const end = positions[1] ? parseInt(positions[1], 10) : total - 1;
const chunksize = (end - start) + 1;
res.writeHead(206, {
"Content-Range": `bytes ${start}-${end}/${total}`,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
const stream = file.createReadStream({ start, end });
pump(stream, res, err => {
if (err) console.error('Stream pipeline failed', err);
});
} catch (err) {
console.error('Error handling stream:', err);
res.status(500).json({ message: 'Error handling stream', err });
}
};
Теперь, когда я нажимаю кнопку потока, я получаю эту ошибку:
Error handling stream: TypeError: Cannot read properties of undefined (reading 'find')
at handleStream (file:///backend/src/api/controllers/movieController.js:72:36)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
речь идет об этой строке кода:
const file = torrent.files.find(file => file.name.endsWith('.mp4')); из функции handleStream.
Я проверил сам торрент, там действительно есть файл .mp4, так что проблема не в этом. Магнитный URI действителен, я смог его скачать, проверить фильм и все такое.
Я проверил значение existingTorrent вstreamMovie с помощью этого утверждения: console.info('existingTorrent:', existingTorrent); и получил такой результат: existingTorrent: Promise { <pending> }.
Я понимаю, что есть проблема с загрузкой торрента или что-то в этом роде, но я действительно запутался, я уже давно застрял на этом. Я просто хочу, чтобы потоковая передача запускалась, когда я нажимаю кнопку трансляции.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Промисы часто используются в асинхронных вызовах, и вам следует правильно await использовать их или использовать .then(fooSometing), короче говоря.
Таким образом, соответствующая строка кода должна быть:
let existingTorrent = await client.get(magnetURI);
Я даже не читал документацию, но мне было любопытно, поэтому здесь написано await для этого метода.