React使用video.js播放RTMP流

video.js在6版本之后是和flash分开的,如果需要使用高版本的,需要额外安装videojs-flash

更新

2020.9.21

publish:已更新至npm仓库

  1. npm包:npm i @antelopecloud/components
  2. README.md

2020.9.9

improve:一些优化

  1. 第一版功能完成
  2. 作为组件,完成打包(暂未发布)
  3. 新增使用文档README.md

2020.9.5

feat:新增独立组件,地址FlashPlayer

  1. 功能:播放RTMP流,新增重连机制
  2. 未全部完成,可以做独立组件自行修改
  3. 使用方法看FlashPlayer.stories.tsx就行了

2020.8.5

docs:新增高版本使用说明;新增@ly-utils/videojs-flash库解决后续报错问题

React使用video.js播放RTMP流

准备

项目有播放rtmp视频流的功能需求,所以搞来搞去还是想着用video.js这个库。

基于react,video.js@5.18.4

yarn add video.js@5.18.4 @types/video.js -D

建议使用 (使用这个库的话后续代码记得修改一下引用库名称)

yarn add @ly-utils/video.js -D

文档:video.js

页面中使用

页面中使用挺简单的

import React, { useMemo, useState, useEffect } from 'react';
import videojs from 'video.js';

// //样式文件注意要加上
import 'video.js/dist/video-js.css';

const Player: React.FC<any> = (props) => {

  const [videoNode, setVideoNode] = useState<any>();
  const [player, setPlayer] = useState<any>();

  const url = 'rtmp://58.200.131.2:1935/livetv/hunantv';

  // rtmp播放
  useMemo(() => {
    if (videoNode) {
      const videoJsOptions = {
        autoplay: true, // 自动播放
        language: 'zh-CN',
        preload: 'auto', // 自动加载
        errorDisplay: true, // 错误展示
        width: 475, // 宽
        height: 300,
        flash: {
          swf: '/video-js.swf',
        },
        sources: [
          {
            src: url,
            type: 'rtmp/flv', // 类型可加可不加,目前未看到影响
          },
        ],
      };
      const videoPlayer = videojs(videoNode, videoJsOptions);
      setPlayer(videoPlayer);
    }
  }, [videoNode]);

  useEffect(() => {
    return (() => {
      if (player) player.dispose()
    })
  }, [])

  return (
    <>
      <div style={{margin:50}}>
        <p>播放器</p>

        <video
          ref={(node) => {
            setVideoNode(node);
          }}
          id="videoPlay"
          className="video-js vjs-default-skin vjs-big-play-centered"
          width="100%"
          height="100%"
        >
          <track kind="captions" />
          <p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
        </video>
      </div>
    </>
  )
}

export default Player;
效果(页面中使用)

页面中

弹框使用
import React, { useMemo, useState, useEffect } from 'react';
import videojs from 'video.js';

// //样式文件注意要加上
import 'video.js/dist/video-js.css';
import { Modal } from 'antd';

const playerModal: React.FC<any> = (props) => {
  const { visible, onClose } = props;

  const [videoNode, setVideoNode] = useState<any>();
  const [player, setPlayer] = useState<any>();

  console.log(1);
  

  const url = 'rtmp://58.200.131.2:1935/livetv/hunantv';

  // rtmp播放
  useMemo(() => {
    if (videoNode) {
      const videoJsOptions = {
        autoplay: true, // 自动播放
        language: 'zh-CN',
        preload: 'auto', // 自动加载
        errorDisplay: true, // 错误展示
        width: 475, // 宽
        height: 300,
        flash: {
          swf: '/video-js.swf',
        },
        sources: [
          {
            src: url,
            type: 'rtmp/flv',
          },
        ],
      };
      const videoPlayer = videojs(videoNode, videoJsOptions);
      setPlayer(videoPlayer);
    }
  }, [videoNode]);

  useEffect(() => {
    return (() => {
      if (player) player.dispose()
    })
  }, [visible])

  const onPlayerClose = () => {
    console.log(1);
    
    onClose()
  }

  return (
    <>
      <Modal
        visible={visible}
        title="预览"
        onOk={onPlayerClose}
        onCancel={onPlayerClose}
        maskClosable={false}
      >
        <video
          ref={(node) => {
            setVideoNode(node);
          }}
          id="videoPlay"
          className="video-js vjs-default-skin vjs-big-play-centered"
          width="100%"
          height="100%"
        >
          <track kind="captions" />
          <p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
        </video>

      </Modal>

    </>
  )
}

export default playerModal;
效果(弹框)

弹框

报错啦

关闭弹框后报错!

this.el_.vjs_getProperty is not a function

主要是会一直报错,然后达到一定次数页面就崩了

报错 this.el_.vjs_getProperty is not a function

解决

1、弹框没了的时候要销毁dispose,我这里放在useEffect中应该是没生效或者说不能解决吧

2、还要配合Modal的销毁子节点apidestroyOnClose

const onPlayerClose = () => {

    onClose()
	// 修改处
    setTimeout(()=>{
      if(player) player.dispose()
    },800)
  }

  return (
    <>
      <Modal
        visible={visible}
        title="预览"
        onOk={onPlayerClose}
        onCancel={onPlayerClose}
        maskClosable={false}
		// 修改处
        destroyOnClose
      >
        <video
          ref={(node) => {
            setVideoNode(node);
          }}
          id="videoPlay"
          className="video-js vjs-default-skin vjs-big-play-centered"
          width="100%"
          height="100%"
        >
          <track kind="captions" />
          <p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
        </video>

      </Modal>

    </>
  )

现在点击隐藏弹框也会出现报错,主要是我用了定时器销毁,如果不用定时器销毁的话,会有一定的视觉差。但是销毁之后就不会再报错了!

究极版

最后还是觉得这个报错不太爽,我就自己去改了一下源码,然后发布在gitee上,想用的话可以这样做

package.js

"video.js": "git+https://gitee.com/jx915/video.js.git"

或者(使用这个库的话后续代码记得修改一下引用库名称)

yarn add @ly-utils/video.js -D

playerModal.tsx

import React, { useState, useEffect } from 'react';
import videojs from 'video.js';

//样式文件注意要加上
import 'video.js/dist/video-js.css';
import { Modal } from 'antd';

const url = 'rtmp://58.200.131.2:1935/livetv/hunantv';

const playerModal: React.FC<any> = (props) => {
  const { visible, onClose } = props;

  const [videoNode, setVideoNode] = useState<any>();
  
  useEffect(() => {
    if (videoNode) {
      const videoJsOptions = {
        autoplay: true, // 自动播放
        language: 'zh-CN',
        preload: 'auto', // 自动加载
        errorDisplay: true, // 错误展示
        width: 475, // 宽
        height: 300,
        flash: {
          swf: '/video-js.swf',
        },
        sources: [
          {
            src: url,
            type: 'rtmp/flv', // 类型可加可不加,目前未看到影响
          },
        ],
      };
      videojs(videoNode, videoJsOptions)
    }
  }, [videoNode])

  const onPlayerClose = () => {
    onClose()
  }

  return (
    <>
      <Modal
        visible={visible}
        title="预览"
        onOk={onPlayerClose}
        onCancel={onPlayerClose}
        maskClosable={false}
        destroyOnClose
      >
        <video
          ref={(node) => {
            setVideoNode(node);
          }}
          id="videoPlay"
          className="video-js vjs-default-skin vjs-big-play-centered"
          width="100%"
          height="100%"
        >
          <track kind="captions" />
          <p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
        </video>

      </Modal>

    </>
  )
}

export default playerModal;
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值