使用 React TypeScript 仅通过 video 标签加载视频
我想做的事情
(yaritai koto)
我正在使用React TypeScript进行开发,并且想要准备嵌入式视频,并实现自动播放!
我用故事的方式写下了我做过的事情的经过。
概要
-
- 视频加载
-
- 自动播放
- 重播功能
有视频库吗?
当我在使用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)错误。
因此,在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的部分出现了错误。
解决方法是创建一个确切能让人确认其存在的情况。
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"
]
}
相关方程
胜利在望!