在 React 中更改播放视频的最佳方法是什么
What is the best way to change a playing video in React
我正在制作一个页面,用于展示我公司的一些内部视频。有五个短视频,所以我想在左边做视频播放器,在右边做一个播放列表,有点像 YouTube 的做法。
但是,我希望能够点击右侧的视频,然后左侧的视频会相应地改变,以及视频播放器下的一些元数据(标题和描述)。
我想要实现的是当点击播放列表组件项目时,这应该传播到 parent 组件并向下传播到视频组件。
目前我的代码如下所示:
const videos = [{
'title' => 'Lorem ipsum',
'short_desc' => '',
'long_desc' => '',
'url' => 'videofile.mp4',
'thumbnail' => 'thumb.jpg',
'length': 55
},{
'title' => 'Lorem ipsum 2',
'short_desc' => '',
'long_desc' => '',
'url' => 'videofile2.mp4',
'thumbnail' => 'thumb2.jpg',
'length': 72
}];
class App extends Component {
constructor() {
super();
this.state = {
videos: videos,
source: videos[0]
}
}
changeVideo(video) {
// Some logig for changing video
}
render() {
let playlist = this.state.videos.map((video, index) => <Playlist key={shortid.generate()} details={video} changeVideo={this.changeVideo.bind(this)} />)
let video = <Video ref="player" source={this.state.source} />
return(
<div className="app">
<section className="left">
{video}
</section>
<section className="right">
{playlist}
</section>
</div>
)
}
}
class Playlist extends Component {
handleClick(e) {
this.props.changeVideo(this);
}
render() {
let {title, length, short_desc, long_desc, thumbnail} = this.props.details;
return(
<div className="playlistItem" onClick={this.handleClick.bind(this)}>
<img src={thumbnail} />
{title}
{short_desc} ({length})
</div>
)
}
}
class Video extends Component {
changeVideo(video) {
// change video
}
render() {
return {
<section className="playerArea">
<Player
ref="player"
poster={this.props.source.thumbnail}
src={this.props.source.url}>
<LoadingSpinner />
<BigPlayButton position="center" />
</Player>
<h1>{this.props.source.title}</h1>
<p>{this.props.source.long_desc}</p>
</section>
}
}
}
我使用的视频播放器是video-reactjs包。
在应用程序中:
constructor(props) {
...
this.changeVideo = this.changeVideo.bind(this);
}
changeVideo(index) {
this.setState({ source: this.state.videos[index] });
}
render() {
let playlist = this.state.videos.map((video, index) => {
<Playlist key={index}
details={video}
changeVideo={this.changeVideo.bind(null, index)} />
})
...remaining code...
在播放列表中:
class Playlist extends Component {
render() {
let {title, length, short_desc, long_desc, thumbnail} = this.props.details;
return(
<div className="playlistItem" onClick={this.props.changeVideo}>
<img src={thumbnail} />
{title}
{short_desc} ({length})
</div>
);
}
}
编辑:替代解决方案,显式绑定 changeVideo
。
我正在制作一个页面,用于展示我公司的一些内部视频。有五个短视频,所以我想在左边做视频播放器,在右边做一个播放列表,有点像 YouTube 的做法。
但是,我希望能够点击右侧的视频,然后左侧的视频会相应地改变,以及视频播放器下的一些元数据(标题和描述)。
我想要实现的是当点击播放列表组件项目时,这应该传播到 parent 组件并向下传播到视频组件。
目前我的代码如下所示:
const videos = [{
'title' => 'Lorem ipsum',
'short_desc' => '',
'long_desc' => '',
'url' => 'videofile.mp4',
'thumbnail' => 'thumb.jpg',
'length': 55
},{
'title' => 'Lorem ipsum 2',
'short_desc' => '',
'long_desc' => '',
'url' => 'videofile2.mp4',
'thumbnail' => 'thumb2.jpg',
'length': 72
}];
class App extends Component {
constructor() {
super();
this.state = {
videos: videos,
source: videos[0]
}
}
changeVideo(video) {
// Some logig for changing video
}
render() {
let playlist = this.state.videos.map((video, index) => <Playlist key={shortid.generate()} details={video} changeVideo={this.changeVideo.bind(this)} />)
let video = <Video ref="player" source={this.state.source} />
return(
<div className="app">
<section className="left">
{video}
</section>
<section className="right">
{playlist}
</section>
</div>
)
}
}
class Playlist extends Component {
handleClick(e) {
this.props.changeVideo(this);
}
render() {
let {title, length, short_desc, long_desc, thumbnail} = this.props.details;
return(
<div className="playlistItem" onClick={this.handleClick.bind(this)}>
<img src={thumbnail} />
{title}
{short_desc} ({length})
</div>
)
}
}
class Video extends Component {
changeVideo(video) {
// change video
}
render() {
return {
<section className="playerArea">
<Player
ref="player"
poster={this.props.source.thumbnail}
src={this.props.source.url}>
<LoadingSpinner />
<BigPlayButton position="center" />
</Player>
<h1>{this.props.source.title}</h1>
<p>{this.props.source.long_desc}</p>
</section>
}
}
}
我使用的视频播放器是video-reactjs包。
在应用程序中:
constructor(props) {
...
this.changeVideo = this.changeVideo.bind(this);
}
changeVideo(index) {
this.setState({ source: this.state.videos[index] });
}
render() {
let playlist = this.state.videos.map((video, index) => {
<Playlist key={index}
details={video}
changeVideo={this.changeVideo.bind(null, index)} />
})
...remaining code...
在播放列表中:
class Playlist extends Component {
render() {
let {title, length, short_desc, long_desc, thumbnail} = this.props.details;
return(
<div className="playlistItem" onClick={this.props.changeVideo}>
<img src={thumbnail} />
{title}
{short_desc} ({length})
</div>
);
}
}
编辑:替代解决方案,显式绑定 changeVideo
。