reactjs - 如何将 hls.js 与 React 结合使用

标签 reactjs material-ui http-live-streaming hls.js

我需要一些帮助来弄清楚如何在 React 中使用 hls.js。 让我解释一下我必须从 api 获取 m3u8 的情况我能够使用 <script> 使其从基本 html 工作标签,但是当我尝试在 React 上实现它时,它不起作用,我们将不胜感激。这是我到目前为止所得到的:

import React, { Component } from "react";

import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
import Grid from "@material-ui/core/Grid";
import ButtonBase from "@material-ui/core/ButtonBase";
import CircularProgress from "@material-ui/core/CircularProgress";

import Hls from "hls.js";

const styles = theme => ({
  root: {
    flexGrow: 1,
    paddingTop: theme.spacing.unit * 2,
    paddingBottom: theme.spacing.unit * 2,
    marginBottom: 24,
    marginLeft: 24,
    marginRight: 60
  },
  image: {
    marginLeft: 24,
    width: 200,
    height: 200
  },
  img: {
    display: "block",
    width: 200,
    height: 200,
    maxWidth: "100%",
    maxHeight: "100%"
  },
  detail: {
    marginLeft: 16
  },
  progress: {
    display: "flex",
    justifyContent: "center",
    alignItems: "center"
  }
});

class Video extends Component {
  constructor(props) {
    super(props);
  }

  componentWillReceiveProps(props) {
    if (props.episode && this.player) {
      var hlsUrl = props.episode.assets.hls;
      var video = this.player;
      if (video.canPlayType("application/vnd.apple.mpegurl")) {
        // If HLS is natively supported, let the browser do the work!
        video.src = "hlsUrl";
        video.addEventListener("loadedmetadata", function() {
          video.play();
        });
      } else if (Hls.isSupported()) {
        // If the browser supports MSE, use hls.js to play the video
        var hls = new Hls({
          // This configuration is required to insure that only the
          // viewer can access the content by sending a session cookie
          // to api.video service
          xhrSetup: function(xhr, url) {
            xhr.withCredentials = true;
          }
        });
        hls.loadSource(hlsUrl);
        hls.attachMedia(video);
        hls.on(Hls.Events.MANIFEST_PARSED, function() {
          video.play();
        });
      } else {
        alert("Please use a modern browser to play the video");
      }
    }
  }

  handleSerieClick = () => {
    this.props.history.push("/" + this.props.serie.apiName);
  };

  _onTouchInsidePlayer() {
    if (this.player.paused) {
      this.player.play();
    } else {
      this.player.pause();
    }
  }

  render() {
    const { classes, theme } = this.props;
    if (this.props.episode) {
      const { assets, title, description, videoId } = this.props.episode;
      return (
        <Grid className={classes.root} item xs={12}>
          <video
            controls
            onClick={this._onTouchInsidePlayer}
            ref={player => (this.player = player)}
            autoPlay={true}
          />
        </Grid>
      );
    } else {
      return (
        <Grid className={classes.progress} item xs={12}>
          <CircularProgress size={100} />
        </Grid>
      );
    }
  }
}

export default withStyles(styles, { withTheme: true })(Video);

这是与 <script> 一起使用的代码标签

<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>

<video id="video"></video>

<script>
  var hlsUrl = 'https://cdn.libcast.net/stream/3de8ff01-18f7-4262-a1f2-abeeb9bb962b/hls/manifest.hls';
  var video = document.getElementById('video');
  if (video.canPlayType('application/vnd.apple.mpegurl')) {
    // If HLS is natively supported, let the browser do the work!
    video.src = 'hlsUrl';
    video.addEventListener('loadedmetadata',function() {
      video.play();
    });

  } else if (Hls.isSupported()) {
    // If the browser supports MSE, use hls.js to play the video
    var hls = new Hls({
      // This configuration is required to insure that only the 
      // viewer can access the content by sending a session cookie
      // to api.video service
      xhrSetup: function(xhr, url) { xhr.withCredentials = true; }
    });
    hls.loadSource(hlsUrl);
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED,function() {
      video.play();
    });

  } else {
    alert('Please use a modern browser to play the video');
  }
</script>

我在 props 和 componentWillRecieveProps 中从父组件传递 hls 源,我尝试使用源来运行播放器

编辑

问题似乎是 <video>当我尝试应用源代码时,标签未定义。

最佳答案

componentWillReceiveProps 中初始化 hls 可能“太早了”。引用是在渲染执行期间创建的,因此您的 this.video 当时可能是 null

尝试将您的逻辑移动到 componentDidMount(如果您从 beginnig 传递适当的 Prop )或至少 componentDidUpdate

关于reactjs - 如何将 hls.js 与 React 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52904439/

相关文章:

iphone - 如何修复 "Error: (-12646:0) Illegal MIME type: text/plain"

javascript - react-router:嵌套路由应该渲染 IndexRoute 组件的子组件还是应该渲染智能父(IndexRoute)组件?

reactjs - react 测试输入是否只接受数字

javascript - 无限滚动不会在 React/Redux 中保留以前的项目

material-ui - 我如何在本地运行 material-ui

image-processing - 如何从 http 网络摄像头直播中捕获图像

reactjs - 当我运行 "npm start"来运行 React 应用程序时,它没有给出任何错误,而是永远挂起

ReactJS MaterialUI 复选框 - 在 onCheck() 中设置状态

reactjs - 使用 makeStyles - useStyles() 全局抛出 'Invalid Hook Call' 错误

FFmpeg HLS 流式传输 - 为什么在中断后重新流式传输时旧段的节目日期时间会发生变化