使用 React 更新 HTML5 视频的源 URL
Posted
技术标签:
【中文标题】使用 React 更新 HTML5 视频的源 URL【英文标题】:Updating source URL on HTML5 video with React 【发布时间】:2017-05-09 06:02:49 【问题描述】:我想更新 html5 视频元素中的源标签,这样当我单击按钮时,正在播放的内容都会切换到新视频。
我有一个 Clip 组件,它返回一个 HTML5 视频元素,源 URL 通过 props 提供。
function Clip(props)
return (
<video controls autoPlay>
<source src=props.url />
</video>
)
我还有一个 Movie 组件,它包含多个 URL,每个 URL 对应于电影的一部分。它还包含一个位置属性,它通过记住当前正在播放的部分来充当迭代器。
class Movie extends Component
constructor()
super();
this.state =
sections: [
'https://my-bucket.s3.amazonaws.com/vid1.mp4',
'https://my-bucket.s3.amazonaws.com/vid2.mp4'
],
position: 0
;
render()
const sections = this.state.sections
const position = this.state.position
return (
<div>
position
<Clip url=sections[position] />
<button onClick=() => this.updatePosition()>Next</button>
</div>
)
updatePosition()
const position = this.state.position + 1;
this.setState( position: position );
Movie 组件呈现一个 Clip 组件和一个“下一步”按钮。单击下一步按钮时,我想更新位置属性并使用部分中的下一个 URL 重新呈现 HTML5 视频元素。
截至目前,当我点击 Next 时,HTML5 视频源标签会更新,但该元素会继续播放上一个 URL 中的视频。谁能帮我弄清楚如何重置视频元素?
更新:我创建了一个 JSFiddle,你可以看到 here。
更新 2: 更新视频元素的 src 属性有效!
【问题讨论】:
你能提供一个jsfiddle吗? 【参考方案1】:又快又脏的遮阳篷: 将key
属性添加到<Clip>
或<video>
,例如:
function Clip( url )
return (
<video key=url>
<source src=url />
</video>
);
推荐的 awnser: 每当有新 URL 时为视频元素触发 load
事件,例如:
function Clip( url )
const videoRef = useRef();
useEffect(() =>
videoRef.current?.load();
, [url]);
return (
<video ref=videoRef>
<source src=url />
</video>
);
解释:视频最初并没有改变,因为本质上你只是在修改 <source>
元素,React 理解 <video>
应该保持不变,所以它不会更新它DOM 并且不会为该源触发新的 load
事件。应该为<video>
触发一个新的load
事件。
肮脏的答案是有效的,因为当您更改 React 元素的 key
时,React 会理解这是一个全新的元素。然后它会在 DOM 中创建一个新元素,该元素自然会在挂载时触发其自己的加载事件。
【讨论】:
我需要使用createRef
而不是useRef
@DanielLizik,那肯定是因为你有一个类组件,对吗?
不,因为我将视频元素 ref 存储在某个第 3 方状态库中。使用useRef
,引用永远不会改变,因此即使source
正确更新,react 仍会继续使用旧的引用;对我来说,它产生了一个奇怪的错误,视频变黑了,但上一个视频的音频继续播放【参考方案2】:
由于某种原因,更改 <source />
的 src 似乎不会切换视频。我不认为这不是反应问题。可能就是<source />
的工作原理。也许您必须再次在该元素上调用.load()
。但是直接在元素本身上设置它更容易。
查看置顶答案的评论:Can I use javascript to dynamically change a video's source?
您可以直接在元素上设置src
:
function Clip(props)
return (
<video src=props.url controls autoPlay>
</video>
)
【讨论】:
我尝试使用您的代码,但也没有用。我从未收到updatePosition
未绑定错误。
当然可以,我的错,你用渲染上的箭头绑定。那就有别的问题了。发布一个jsfiddle。不过,您仍然应该在函数上执行此操作
@Gundam194 这不起作用,因为您没有在构造函数中传递道具。 jsfiddle.net/d0exvp02/2。更改 src 似乎不会导致视频从新网址开始
@Gundam194 立即查看答案【参考方案3】:
将 URL 绑定在 Video 标签的 src 属性中,而不是 Source 标签中
【讨论】:
【参考方案4】:向第二个视频添加父 div 我的代码:
isMobile ? (
<video
autoPlay=true
loop
className="moviles"
muted
playsInline
poster="/totto/kids.png"
>
<source src="/totto/losmoviles.webm"></source>
<source src="/totto/losmoviles.mp4"></source>
</video>
) : (
<div>
<video
autoPlay=true
loop
className="moviles2"
muted
playsInline
poster="/totto/portada.jpg"
>
<source src="/totto/moviles.webm"></source>
<source src="/totto/moviles.mp4"></source>
</video>
</div>
)
【讨论】:
【参考方案5】:你可以使用key属性:
<video key=videoUrl autoPlay >
<source src=videoUrl type="video/mp4"></source>
</video>
如果视频的key属性发生变化,视频组件会被重新挂载
【讨论】:
以上是关于使用 React 更新 HTML5 视频的源 URL的主要内容,如果未能解决你的问题,请参考以下文章
尝试将 MediaSource 对象附加为 HTML5 视频标签的源时出现“不允许加载本地资源”错误