IOS H5页面中 HLS视频无法正常播放,使用hls.插件

IOS H5页面中 HLS视频无法正常播放,使用hls.插件

HLS.js依靠 HTML5 视频和 MediaSource Extensions 进行播放。

所有 iPhone 浏览器 (iOS) 都没有可用的 MediaSourceExtension,因此Hls.js将不起作用。如果您在 iPhone 上检查 Hls.isSupported() ,您会看到该函数返回 false

  if (Hls.isSupported()) {
    var hls = new Hls();
    hls.loadSource(videoSrc);
    hls.attachMedia(video);
  } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    video.src = videoSrc;
  }

iOS 可以使用普通的 <video><source></video> HTML,因为 Safari 具有原生 HLS 支持。初始化 Hls.js <video> 将阻止本机 HLS 功能根本无法工作。

Hls.isSupported return true

但这个解决方案对我不起作用,因为Hls.isSupported 总是返回 true。我做了以下调整以使其正常工作:

React:

import Hls from "hls.js";
import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";

interface PlayerProps {
  src?: string;
  poster: string;
  onPlay(): void;
  onPlayFailed(): void;
}

export const Player = forwardRef<{}, PlayerProps>(({ src, poster, onPlay, onPlayFailed }, ref) => {
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const hlsRef = useRef<Hls | null>(null);

  useEffect(() => {
    if (!src || !videoRef.current) return;
    const supportHLS = Boolean(videoRef.current.canPlayType("application/vnd.apple.mpegurl"));

    if (supportHLS) {
      videoRef.current.src = src;
      videoRef.current.play().then(onPlay).catch(onPlayFailed);
    } else {
      hlsRef.current = new Hls();
      const hls = hlsRef.current;

      hls.on(Hls.Events.MEDIA_ATTACHED, function () {
        videoRef.current!.play().then(onPlay).catch(onPlayFailed);
      });
      hls.loadSource(src);
      hls.attachMedia(videoRef.current);
      
      return () => {
          hls.destroy();
      };
    }
  }, [src]);

  useImperativeHandle(ref, () => videoRef.current!, []);

  return (
    <video className="w-full h-full object-cover" playsInline ref={videoRef} poster={poster}>
      <source src={src} type="application/x-mpegURL"></source>
    </video>
  );
});

Vue:

然后,你可以在 Vue 组件中这样使用它:

<template>  
  <video  
    class="w-full h-full object-cover"  
    playsinline  
    :poster="poster"  
    @play="onPlay"  
    @error="onPlayFailed"  
    ref="videoElement"  
  >  
    <source :src="src" type="application/x-mpegURL"></source>  
  </video>  
</template>  
  
<script>  
import Hls from 'hls.js';  
  
export default {  
  props: {  
    src: {  
      type: String,  
      default: ''  
    },  
    poster: {  
      type: String,  
      required: true  
    }  
  },  
  data() {  
    return {  
      hlsInstance: null  
    };  
  },  
  mounted() {  
    this.initializePlayer();  
  },  
  beforeDestroy() {  
    if (this.hlsInstance) {  
      this.hlsInstance.destroy();  
      this.hlsInstance = null;  
    }  
  },  
  methods: {  
    initializePlayer() {  
      if (!this.src || !this.$refs.videoElement) return;  
      const supportsHLS = this.$refs.videoElement.canPlayType('application/vnd.apple.mpegurl');  
  
      if (supportsHLS) {  
        this.$refs.videoElement.src = this.src;  
        this.$refs.videoElement.play().then(this.onPlay).catch(this.onPlayFailed);  
      } else {  
        this.hlsInstance = new Hls();  
        const hls = this.hlsInstance;  
  
        hls.on(Hls.Events.MEDIA_ATTACHED, () => {  
          this.$refs.videoElement.play().then(this.onPlay).catch(this.onPlayFailed);  
        });  
        hls.loadSource(this.src);  
        hls.attachMedia(this.$refs.videoElement);  
      }  
    },  
    onPlay() {  
      this.$emit('onPlay');  
    },  
    onPlayFailed() {  
      this.$emit('onPlayFailed');  
    }  
  },  
  watch: {  
    src() {  
      this.initializePlayer();  
    }  
  }  
};  
</script>  
  
<style scoped>  
/* Add your styles here */  
</style>

在这个 Vue 组件中,我们使用了 Vue 的生命周期钩子 mounted 来初始化播放器,并在 beforeDestroy 钩子中销毁 hls.js 实例以避免内存泄漏。data 对象用来存储 hls.js 的实例。methods 包含了初始化播放器的方法以及处理播放和播放失败的方法。

此外,我们使用 watch 选项来监听 src 属性的变化,如果它变化了,我们重新初始化播放器。

最后,我们通过 $refs 访问到 DOM 元素,这和 React 中的 useRef 类似。我们还通过 $emit 触发自定义事件,以便父组件可以监听这些事件。

注意:在模板中,我们使用 :src="src":poster="poster" 来绑定属性,这和 React 中的属性绑定类似。

确保在父组件中监听 onPlayonPlayFailed 事件,就像这样:

<template>  
  <Player :src="videoSrc" :poster="videoPoster" @onPlay="handlePlay" @onPlayFailed="handlePlayFailed"></Player>  
</template>  
  
<script>  
import Player from './Player.vue';  
  
export default {  
  components: {  
    Player  
  },  
  data() {  
    return {  
      videoSrc: 'your-video-source-url',  
      videoPoster: 'your-poster-image-url'  
    };  
  },  
  methods: {  
    handlePlay() {  
      // 处理播放事件  
    },  
    handlePlayFailed() {  
      // 处理播放失败事件  
    }  
  }  
};  
</script>

画面为初始页面,视频进度会走,有声音

但使用之后,发现项目中的hls视频加载成功,可以播放,但是播放只有声音,画面为初始的画面,调查打断点之后,发现解决方案

<template>
  <div class="hls-video-player">
    <video
      class="videoElement"
      ref="videoElement"
      autoplay
      muted
      preload="true"
      playsinline="true" webkit-playsinline="true"
      @loadedmetadata="onLoadedMetadata"
      controls
    >
      <source :src="hlsUrl" type="application/x-mpegURL"/>
    </video>
  </div>
</template>

<script>
import Hls from 'hls.js'
export default {
  name: 'HlsVideoPlayer',
  props: {
    hlsUrl: {
      type: String,
      required: true
    }
  },
  data () {
    return {
      hlsInstance: null
    }
  },
  mounted () {
    this.initializePlayer()
  },
  beforeDestroy () {
    if (this.hlsInstance) {
      this.hlsInstance.destroy()
      this.hlsInstance = null
    }
  },
  methods: {
    onLoadedMetadata () {
      console.log('Video metadata loaded')
    },
    initializePlayer () {
      if (!this.hlsUrl || !this.$refs.videoElement) return
      const supportsHLS = this.$refs.videoElement.canPlayType('application/vnd.apple.mpegurl')
      console.log(Hls.isSupported(), supportsHLS, 'hls.isSupported', 'supportsHLS')
      // if (supportsHLS) {
      //   this.$refs.videoElement.src = this.hlsUrl
      //   this.$refs.videoElement.play().then(this.onPlay).catch(this.onPlayFailed)
      // } else {
      //   this.hlsInstance = new Hls()
      //   const hls = this.hlsInstance
      //   hls.on(Hls.Events.MEDIA_ATTACHED, () => {
      //     this.$refs.videoElement.play().then(this.onPlay).catch(this.onPlayFailed)
      //   })
      //   hls.loadSource(this.hlsUrl)
      //   hls.attachMedia(this.$refs.videoElement)
      // }
      if (Hls.isSupported()) {
        // 如果支持 hls.js(MediaSource Extensions)
        this.hlsInstance = new Hls()
        const hls = this.hlsInstance
        hls.on(Hls.Events.MEDIA_ATTACHED, () => {
          this.$refs.videoElement.play().then(this.onPlay).catch(this.onPlayFailed)
        })
        hls.loadSource(this.hlsUrl)
        hls.attachMedia(this.$refs.videoElement)
      } else if (supportsHLS) {
        // 如果支持原生播放
        // video.src = url
        // // 自动播放
        // video.addEventListener('canplay', function () {
        //   video.play()
        // })
        this.$refs.videoElement.src = this.hlsUrl
        this.$refs.videoElement.play().then(this.onPlay).catch(this.onPlayFailed)
      }
    },
    onPlay () {
      console.log('onPlay')
      // this.$emit('onPlay')
    },
    onPlayFailed () {
      console.log('onPlayFailed')
      // this.$emit('onPlayFailed')
    }
  },
  watch: {
    hlsUrl () {
      this.initializePlayer()
    }
  }
}
</script>

<style scoped>
.hls-video-player {
  width: 100%;
  max-width: 600px; /* 或其他你需要的宽度 */
  margin: 0 auto;
  display: flex;
  margin: 0 auto;
  justify-content: center;
  align-items: center;
}
.videoElement{
  width: 100%;
}
</style>

### 回答1: H5播放HLS(Hypertext Live Streaming)是指使用HTML5技术在网页播放HLS格式的视频流。HLS是一种基于HTTP协议的流媒体传输协议,它通过将视频流分割成小的TS文件,并使用M3U8文件作为索引,实现视频的分段加载和播放。 为了在网页实现H5播放HLS,可以使用hls.js库(hls.min.js)。hls.js是一个开源的JavaScript库,它提供了一个HLS播放器,可以在支持HTML5的浏览器播放HLS视频使用hls.js库,需要在网页引入hls.min.js文件,并创建一个Hls对象。然后,根据视频地址创建一个video元素,并将其作为参数传递给Hls对象的attachMedia方法。接下来,可以监听Hls对象的一些事件(如Hls.Events.MANIFEST_PARSED),根据需要设置一些配置选项,如自动播放、循环播放等。最后,调用Hls对象的loadSource方法并传入视频地址,开始加载并播放HLS视频使用hls.js库,可以实现在网页插件播放HLS视频,而无需依赖Flash等第三方插件。它还提供了一些功能,如自适应码率切换、缓冲控制、清晰度切换等,来提升用户体验。总的来说,hls.js库为开发者提供了一种简单、可靠的方式来实现H5播放HLS视频的功能。 ### 回答2: h5播放HLS(HTTP Live Streaming)是一种流媒体传输协议,可以在网络不稳定或带宽较低的情况下流畅播放视频。为了实现在H5页面播放HLS格式的视频,我们可以使用hls.min.js库。 hls.min.js是一个开源的JavaScript库,它是HLS.js的压缩版本。HLS.js是一个在Web平台上实现HLS播放JavaScript库,它使用Media Source Extension(MSE)技术来实现HLS的解析和播放。 在使用hls.min.js之前,我们需要先在HTML页面引入该库的脚本。可以通过在<script>标签增加src属性指向hls.min.js文件所在的URL来进行引入。例如: <script src="hls.min.js"></script> 接下来,我们需要创建一个HLS对象并将其绑定到video元素上。这可以通过以下代码来实现: var videoElement = document.getElementById('video'); var hls = new Hls(); hls.loadSource('video_url.m3u8'); hls.attachMedia(videoElement); 在上面的代码,videoElement是我们在HTML定义的video元素,'video_url.m3u8'是HLS视频流的URL。通过loadSource()方法来加载HLS视频流,并通过attachMedia()方法将HLS对象绑定到video元素上。 最后,我们需要监听HLS对象的一些事件来处理播放状态的变化。例如,我们可以监听HLS对象的'Hls.Events.MANIFEST_PARSED'事件来确保视频流已经解析完毕并可以开始播放hls.on(Hls.Events.MANIFEST_PARSED, function() { videoElement.play(); }); 通过以上步骤,我们就可以在H5页面使用hls.min.js库来播放HLS格式的视频了。 ### 回答3: hls.min.js是一个用于播放HLS(HTTP Live Streaming)视频JavaScript库。HLS是一种基于HTTP的流媒体传输协议,它将视频切分成小片段,并通过HTTP协议逐个下载和播放这些片段。 hls.min.js库可以实现在支持HTML5的浏览器播放HLS视频流。它提供了一些API和事件监听器,用于控制和管理视频播放。 首先,我们需要在HTML页面引入hls.min.js库文件。然后,通过创建一个新的Hls对象来初始化播放器。使用Hls对象的loadSource方法可以加载一个HLS视频流的URL。一旦视频流加载完毕,可以通过调用Hls对象的attachMedia方法将视频流与HTML的video元素关联起来。 hls.min.js库还提供了一些事件监听器,例如在视频播放开始或结束时触发的事件。我们可以通过添加这些事件监听器来执行自定义的操作,例如在视频播放结束后自动加载下一个视频片段。 此外,hls.min.js还支持视频流的动态切换。如果视频有多个分辨率或质量选项,可以通过调用Hls对象的startLoad或nextLevel方法来切换视频的质量。 总之,hls.min.js库是一个方便并且易于使用的工具,可以使开发者在HTML5实现HLS视频播放。它提供了一系列的API和事件监听器,用于控制和管理视频播放过程,并且支持视频流的动态切换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值