WebTorrent: TypeError: невозможно прочитать свойства неопределенного значения (чтение «найти»)

Я работаю над школьным проектом, создаю какой-то стриминговый сайт. Предполагается, что я смогу транслировать фильм с помощью 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> }. Я понимаю, что есть проблема с загрузкой торрента или что-то в этом роде, но я действительно запутался, я уже давно застрял на этом. Я просто хочу, чтобы потоковая передача запускалась, когда я нажимаю кнопку трансляции.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Промисы часто используются в асинхронных вызовах, и вам следует правильно await использовать их или использовать .then(fooSometing), короче говоря.

Таким образом, соответствующая строка кода должна быть:

let existingTorrent = await client.get(magnetURI);

Я даже не читал документацию, но мне было любопытно, поэтому здесь написано await для этого метода.

Другие вопросы по теме