如何在反应中使用 hls.js

Posted

技术标签:

【中文标题】如何在反应中使用 hls.js【英文标题】:How to use hls.js with react 【发布时间】:2018-10-20 09:55:49 【问题描述】:

我需要一些帮助来了解。 让我解释一下我必须从 api 获取 m3u8 的情况.这是我到目前为止所得到的:

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

这是与&lt;script&gt; 标签一起使用的代码

<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 源,我尝试使用源来运行播放器

编辑

问题似乎是当我尝试应用源时,&lt;video&gt; 标签未定义。

【问题讨论】:

【参考方案1】:

componentWillReceiveProps 中启动 hls 可能“为时过早”。 Refs 是在渲染执行期间创建的,因此您的 this.video 在那时可能是 null

尝试将您的逻辑转移到componentDidMount(如果您从一开始就传递了适当的道具)或至少componentDidUpdate

【讨论】:

以上是关于如何在反应中使用 hls.js的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Hls.js 在准备好后自动播放视频?

如何使用 hls.js 和 plyr 配置多个视频实例

如何让 HLS.js 从服务器端获取数据?

hls.js CORS 使用 AWS Cloudfront 的 Cookie 问题

如何使用带有字符串而不是 m3u8 播放列表的 loadSource()?

HLS.js 获取视频片段信息