我的项目须要一个列表循环播放视频的性能,应用的是阿里云公有加密,先说一下实现思路。

  • 申请视频列表数据
  • 首次默认第一条视频列表数据
  • 自动播放第一条数据
  • 播放完结自动更新索引值加载下一个视频。

因为播放器是须要dom构造加载的,所以须要应用componentDidMount办法加载渲染播放器,
咱们页面加载的第一次申请将通过它实现。

阿里云播放器自定义组件
我给自定义播放组件提供了componentWillReceiveProps办法,用于跟踪配置文件变动,重载播放器播放视频。

接下来是实现的代码

import React from 'react';import Router, {withRouter} from 'next/router'import styles from './index.module.scss'import Aliplayer from "@/components/aliplay";import Head from 'next/head'export default withRouter(    class PlayList extends React.Component {        constructor(props) {            super(props);            this.handleCoursePlayBtnClick = this.handleCoursePlayBtnClick.bind(this)            this.videoPlayer = React.createRef();        }        state = {            showDataSource: [],            showPlayer: false,            instance: null,            playNextStatus: true,            selectedPlayIndex: 0,        }        componentDidMount() {            this.init()        }        async init() {            const response = await api.getList()            try {                var data = response.data || []                if (data.length > 0) {                    let firstVideo = data[0]                    this.setState({selectedPlayIndex: 0})                    this.getInfo(firstVideo.vid)                }                this.setState({showDataSource: data})            } catch (e) {            }        }        handleCoursePlayBtnClick(index, vid) {            this.getInfo(vid)            this.setState({selectedPlayIndex: index})        }        async getInfo(vid) {            var playerConfig = {                vid: "",                playauth: "",                width: '100%',                height: '100%',                autoplay: true, // 自动播放                useH5Prism: true, // 播放器类型:html5                preload: true,            }            if (!vid) {                throw Error("未提供vid")            }            var video = {}            const responseVideo = await api.getAuth(video.videoSourceId)            try {                playerConfig.playauth = responseVideo.playAuth            } catch (e) {                delete playerConfig.playauth                delete playerConfig.vid            }            this.setState({                video: video,                playerConfig: playerConfig,            })            // console.log("课程加载实现", playerConfig,this.state.showPlayer)        }        onGetInstance = (player) => {            let that = this            player.on('ended', async function (e) {                if (that.state.playNextStatus) {                    that.setState({playNextStatus: false})                    that.playNextVideo()                }                setTimeout(() => {                    that.setState({playNextStatus: true})                    clearTimeout()                }, 800)                // console.log("播放器完结播放", e)            })            player.on('playing', function (e) {                console.log("播放中")            })            player.on('ready', function (e) {                console.log("视频准备就绪,行将播放")            });            player.on('error', function (e) {                console.log("呈现谬误", e)            });            player.on('autoplay', function (data) {                //能够自动播放 data.paramData            })        }        playNextVideo = () => {            let that = this            const dataSource = that.state.dataSource            let index = (dataSource.length > that.state.selectedPlayIndex + 1) ? (that.state.selectedPlayIndex + 1) : 0;            let id = dataSource[index] && dataSource[index].id            that.getInfo(id)            that.setState({selectedPlayIndex: index})        }        render() {            const {showDataSource, selectedPlayIndex, playerConfig, showPlayer} = this.state            return (                <div className="match video-page">                    <Head>                        <script src={'https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js'}                                type={'text/javascript'}/>                        <link href={'https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css'}                              rel={'stylesheet'}/>                    </Head>                    <div className={styles.main + " row match content-start"}>                        <div className={styles.videoListBox + "  h-match cell-scroll-y"}>                            <div className={styles.listBtn}>                                <img className={styles.listBtnIcon} alt="" src={"/logo_sign.png"}/>                            </div>                            <div className="col content-start match">                                <ul className={styles.videoList}>                                    {showDataSource && showDataSource.map((video, i) => {                                        return (                                            <li className={styles.videoCard + " " + (selectedPlayIndex === i && styles.videoCardActived)}                                                key={i}>                                                <div className="w-match p-2 col">                                                    <div className={styles.imageBox}                                                         onClick={() => this.handleCoursePlayBtnClick(i, video.id)}>                                                        <img className={styles.videoImage} alt=""                                                             src={video.videoCover}/>                                                    </div>                                                    <div className={styles.title}                                                         onClick={() => this.handleCoursePlayBtnClick(i, video.id)}>{video.title}&nbsp;</div>                                                </div>                                            </li>                                        )                                    })}                                </ul>                            </div>                        </div>                        <div className={styles.playerContainer + " match bg-black"}>                            <div className={styles.videoContainer}>                                <div ref={this.videoPlayer} style={{height: this.state.height}}                                     className={"col " + styles.videoBox}>                                    {(showPlayer && playerConfig) && <Aliplayer                                        config={playerConfig}                                        onGetInstance={instance => this.onGetInstance(instance)}                                    />}                                </div>                            </div>                        </div>                    </div>                </div>            );        }    })

这里是开发过程中发现并解决的几个点:
1、播放器在完结播放并进行下一个视频播放时,会屡次触发ended事件,其问题本源就是该播放器状态为完结时,我进行切换下个视频,此时ended事件再次或屡次激活,导致跳过多个视频。
2、循环播放列表须要对index索引判断,进行播放视频内容更新;

目前的解决方案是做一个状态标记,通过计时器解决该问题;

这里是开发过程中发现未解决的几个点:
1、首次网页加载须要点击能力进行自动播放;