UseEffect и элемент видео не работают должным образом

У меня есть элемент видео, у которого есть ссылка, которую можно использовать для получения его свойств. По-моему, довольно стандартная вещь. Проблема в том, что при запуске эффекта элемент видео (в videoRef.current) регистрируется и имеет свойство продолжительности, равное 311, но под ним, где я пытаюсь зарегистрировать само свойство продолжительности, не работает. Он регистрирует NaN.

Вот код, соответствующий вопросу.

const Home = () => {
    const [videoState, setVideoState] = useState({
        playing: false,
        currentTime: 0,
        volume: "50%",
        playbackSpeed: 1,
        totalTime: 0,
    })
    const videoRef = useRef<HTMLVideoElement>(null)

    

    useEffect(() => {
        if (videoRef.current) {
            console.dir(videoRef.current)
            console.info(+videoRef.current.duration)
            // console.info(typeof(videoRef.current.duration))
            // @ts-ignore
            setVideoState((prev) => ({ ...prev, totalTime: videoRef.current.duration }))
        }
    }, [])

    return (
        <div className='p-8 bg-red-500 w-full h-full relative'>
            <div className='relative w-fit h-fit'>
                <video
                    src = {fall}
                    ref = {videoRef}
                    // onPlaying = {handleTimeUpdate}
                    onTimeUpdate = {handleTimeUpdate}
                ></video>
        </div>
    )
}
export default Home

выход

и в видеообъекте есть цифра продолжительности

Я не понимаю, почему продолжительность видеообъекта равна 311 при выходе из системы, но это NaN, когда он регистрируется напрямую.

Я ожидал, что во втором журнале будут записаны данные о продолжительности.

Я думаю, вы пропустили «видео». правильно должно быть console.info(+videoRef.current.video.duration)

Bhanu Pratap 07.06.2024 14:22

У элемента video нет свойства video. Даже с console.info(+videoRef.current.duration) там всё равно написано NaN

Mukadas Maltiti 07.06.2024 17:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
2
110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете посмотреть этот вопрос => Получение продолжительности видео HTML5 отдельно от файла

Проблема в том, что свойство продолжительности доступно после загрузки метаданных. Вам нужно подождать этого.

попробуйте использовать этот useEffect

useEffect(() => {
        const handleDurationChange = () => {
            if (videoRef.current) {
                console.dir(videoRef.current);
                console.info(videoRef.current.duration);
                setVideoState((prev) => ({ ...prev, totalTime: videoRef.current.duration }));
            }
        };

        if (videoRef.current) {
            videoRef.current.addEventListener('durationchange', handleDurationChange);
        }

        return () => {
            if (videoRef.current) {
                videoRef.current.removeEventListener('durationchange', handleDurationChange);
            }
        };
    }, []);

Чтобы понять, вы можете скопировать/вставить этот фрагмент в консоль браузера:

const obj = { a: 1, b: 2 };
console.dir(obj); // => you will see { a: 3, b: 2 } in the browser
console.dir({ ...obj }); // => you will see { a: 1, b: 2 } in the browser
obj.a = 3;

когда вы передаете объект напрямую, браузер сохраняет ссылку на него, и если он изменится, он отобразит мутированный объект (с новым состоянием)

Если вы хотите «захватить» состояние console.dir на момент, вам необходимо передать копию объекта.

Это сработало, спасибо. Я до сих пор не понимаю, почему длительность была действительна, когда видеообъект был открыт в консоли браузера, но NaN при регистрации из кода.

Mukadas Maltiti 08.06.2024 19:22

Добавляю еще пояснения, подскажите, если непонятно.

Dorian Massoulier 08.06.2024 22:29

Думаю, я понял. Итак, в моем случае браузер хранит videoRef.current в памяти и обновляет его значения при загрузке метаданных. Но доступ только к продолжительности из videoRef.current создает отдельную переменную?

Mukadas Maltiti 09.06.2024 00:46

Объект тот же. Когда вы используете console.info(videoRef.current.duration), продолжительность видео еще недоступна, поэтому она отображается как NaN. Когда вы вручную открываете объект в браузере, проходит некоторое время, позволяющее загрузить метаданные. Затем объект мутирует в течение доступной продолжительности.

Dorian Massoulier 09.06.2024 14:59

Это все объясняет. Спасибо, что нашли время объяснить мне это. Я очень благодарен!

Mukadas Maltiti 10.06.2024 03:39

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