使用 React TypeScript 仅通过 video 标签加载视频

我想做的事情

(yaritai koto)

我正在使用React TypeScript进行开发,并且想要准备嵌入式视频,并实现自动播放!

我用故事的方式写下了我做过的事情的经过。

概要

    1. 视频加载

 

    1. 自动播放

 

    重播功能

有视频库吗?

 

当我在使用React进行开发时,我想要播放视频!当我搜索时,会出现一些相关的库。这意味着我必须使用这些库吗?为了弄清楚这个问题,我尝试了不使用库来实现,看看会发生什么。

总的来说,由于浏览器的用户代理样式表,它的外观相对丰富,所以根据用途不同,可能不需要使用库。此外,这种方法似乎也适用于插入背景视频。在此基础上,加入lazyload等技术可能会更好。

提供以下的中文翻译:

代碼

突然出现了子组件,看起来是这样的。

import React, { useRef, useEffect } from 'react'
import video_mp4 from "../movie/sample.mp4"
import video_webm from "../movie/sample.webm"

export function Translate() {
    const videoRef = useRef<HTMLVideoElement>(null);
    useEffect(() => {
        videoRef.current?.play();
    }, []);
    return (
        <React.StrictMode>
                    <video controls muted ref={videoRef} >
                        <source src={video_mp4} type="video/mp4" />
                        <source src={video_webm} type="video/webm" />
                        <p>Your browser doesn't support HTML5 video.</p>
                    </video>
        </React.StrictMode>
    );
}

尝试导入动画。

import video_mp4 from "../movie/sample.mp4"
import video_webm from "../movie/sample.webm"

将视频包含在源中。

TS(2307)

在这个时候,当导入mp4和webm格式的时候,会出现ts(2307)错误。

无法找到模块../movie/sample.mp4或相应的类型声明。ts(2307)

因此,在react-app-env.d.ts中添加declare语句。

/// <reference types="react-scripts" />
declare module '*.mp4' {
    const src: string;
    export default src;
}
declare module '*.webm' {
    const src: string;
    export default src;
}

在网页中添加video标签.

用代码定义视频,并显示之前的视频。

 <video controls muted ref={videoRef} >

当写下 controls 时,它会设定用户代理样式表中的播放按钮等。若要放置背景视频之类的元素,则可以将 controls 删除即可。在 ref 中,我们使用 useRef() 设置了一个引用,这个将在后面进行解释。

<source src={video_mp4} type="video/mp4" />

在这里,我们将先前包含在源代码中的视频指定为替代视频列表中的视频。在用户界面中,将使用源代码中的其中一个视频。

自主恢复

然而,仅指定了源(source)并不会自动播放视频。如果给

useEffect(() => {
  videoRef.current?.play();
}, []);

在 useEffect() 中触发 HtmlVideoElement 的 play() 方法,以在渲染完成后播放视频。

我希望增加一个回放按钮!

「竟然有视频!从一开始就给我看!」
「要我在播放控制里用鼠标拖动滑块?别说麻烦的话!」
为了满足这个要求,我们决定添加一个重播按钮。

点击按钮后,尝试添加一个功能,使视频能够返回到开头。

import React, { useRef, useEffect } from 'react'
import video_mp4 from "../movie/sample.mp4"
import video_webm from "../movie/sample.webm"
+ import { Button } from '@material-ui/core';

export function Translate() {
    const videoRef = useRef<HTMLVideoElement>(null);
    useEffect(() => {
        videoRef.current?.play();
    }, []);
+    const StartReplay = () => {
+       videoRef.current?.currentTime = 0;
+    }
    return (
        <React.StrictMode>
                    <video controls muted ref={videoRef} >
                        <source src={video_mp4} type="video/mp4" />
                        <source src={video_webm} type="video/webm" />
                        <p>Your browser doesn't support HTML5 video.</p>
                    </video>
+                    <Button onClick={StartReplay} children="replay" variant="contained" color="primary" />
        </React.StrictMode>
    );
}

当前时间开始

让我们来看一下代码的说明。

如果将 HtmlVideoElement 的属性currentTime设置为零,我们知道视频将会回到开头。因此,我们准备了一个名为StartReplay的函数,在其中放置了操作currentTime的代码。

const StartReplay = () => {
   videoRef.current?.currentTime = 0;
}

请原生地用中文重新表达以下内容,只需要一个选项:TS(2779)

现在出现了问题。currentTime的部分出现了错误。

无法在替换式的左边指定可省略的属性访问。ts(2779)

解决方法是创建一个确切能让人确认其存在的情况。

const StartReplay = () => {
    if (videoRef.current?.currentTime) {
        videoRef.current.currentTime = 0;
    }
}

这样错误就解决了。

只是回到了最初的地方

我认为这样就可以了,但是很遗憾。这样的话,在视频结束后,重播按钮就无法使用了。表明视频中光标的当前时间currentTime和负责播放和停止的play()是两个不同的问题。

const StartReplay = () => {
    if (videoRef.current?.currentTime) {
        videoRef.current.currentTime = 0;
    }
    videoRef.current?.play();
}

在将currentTime设置为零后,使用play()方法开始播放。

总结

让我们最后总结一下。

import React, { useRef, useEffect } from 'react'
import video_mp4 from "../movie/sample.mp4"
import video_webm from "../movie/sample.webm"
+ import { Button } from '@material-ui/core';

export function Translate() {
    const videoRef = useRef<HTMLVideoElement>(null);
    useEffect(() => {
        videoRef.current?.play();
    }, []);
+    const StartReplay = () => {
+       if (videoRef.current?.currentTime) {
+        videoRef.current.currentTime = 0;
+        }
+        videoRef.current?.play();
+    }
    return (
        <React.StrictMode>
                    <video controls muted ref={videoRef} >
                        <source src={video_mp4} type="video/mp4" />
                        <source src={video_webm} type="video/webm" />
                        <p>Your browser doesn't support HTML5 video.</p>
                    </video>
+                    <Button onClick={StartReplay} children="replay" variant="contained" color="primary" />
        </React.StrictMode>
    );
}

环境

    create-react-app : 4.0.3
    react : 17
    typescript : 4
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

相关方程

胜利在望!

广告
将在 10 秒后关闭
bannerAds