简体   繁体   English

如何将hls.js与react一起使用

[英]How to use hls.js with react

I need some help trying to figure how to use hls.js in react. 我需要一些帮助来尝试确定如何在反应中使用hls.js。 Let me explain the situation I have to fetch the m3u8 from an api I'm able to make it work from a basic html with the <script> tag but when i try to implement it on react it doesn't work any help is appreciated. 让我解释一下我必须从api提取m3u8的情况,我能够使用<script>标记从基本html使其运行,但是当我尝试在React上实现它时,它无法正常工作,不胜感激。 This is what I've got so far: 到目前为止,这是我得到的:

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);

This is the code that works with <script> tag 这是与<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>

I pass the hls source from a parent component in the props and in componentWillRecieveProps i try to use the source to run the player 我在道具和componentWillRecieveProps中从父组件传递hls源,我尝试使用源来运行播放器

EDIT 编辑

THe problem seems to be that <video> tag is undefined when I try to apply the source. 问题似乎是当我尝试应用源时<video>标签未定义。

Initing hls in componentWillReceiveProps is probably "too early". componentWillReceiveProps初始化hls可能为时过早。 Refs are created during the render execution so your this.video is probably null at that time. this.video是在渲染执行期间创建的,因此您的this.video可能为null

Try moving your logic into componentDidMount (if you pass proper props from the beginnig) or at least componentDidUpdate . 尝试将逻辑移至componentDidMount (如果从beginnig传递了正确的道具)或至少移至componentDidUpdate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM