Vue实现直播功能:从RTMP到HLS视频流加载指南

作者:松果

时间:2026-10-25

浏览:112

本文总结在Vue项目中实现监控直播功能的实践过程。针对主流浏览器不再支持Flash的问题,分析了RTMP与HLS两种视频流格式的优劣。详细讲解了使用video.js和ckplayer加载RTMP流的局限性,并重点提供了基于hls.js在Vue中加载HLS视频流的完整代码实现与配置步骤,帮助开发者解决实时音视频播放难题。

文章目录

前言

近期在开发过程中,需要实现一个类似直播效果的监控站点图像播放功能,特此记录并总结整个实现过程。

该功能最初后台提供的是rtmp格式的视频流,经过调研发现,rtmp视频流依赖flash播放器,而目前各大主流浏览器已全面弃用flash,因此最终调整为使用hls格式的视频流,从而成功实现了该功能(若只需获取成功运行的代码,可直接参考第三部分:vue加载hls视频流)。

一、视频流是什么?

  • 视频流即流媒体(streaming media),指将连续数据压缩后通过网络分段发送,实现即时音视频传输的技术。监控、直播等实时播放功能通常均采用流媒体技术。
  • 流媒体协议:这是一种标准化的视频传输方法,将视频分解为多个数据块发送给播放器,由播放器重新组合播放。常见的协议包括rtmp、hls、hds、mss、MPEG-DASH等。
  • 视频格式(format):指视频文件的容器格式。常见的容器格式包括 .mp4、.m4v、.avi、.mov等。

上述三种定义在此不做过多展开,感兴趣者可自行深入查阅;rtmp视频流即基于rtmp流媒体协议生成的流媒体,hls视频流同理(此类视频流的格式通常由后台控制)。

二、vue加载rtmp视频流

1.方法一:video.js

npm install --save vue-video-player
npm install --save videojs-flash
<template>
    <div class="box">
        <section id="video" class="video-js vjs-default-skin" ref="viodeRef"></section>
    </div>
</template>
<script>
    import Video from 'video.js'
    import 'video.js/dist/video-js.min.css'
  export default {
    name: 'video-play-box',
    mounted(){
      this.player = Video('video', {
        //确定播放器是否具有用户可以与之交互的控件。没有控件,启动视频播放的唯一方法是使用autoplay属性或通过Player API。
        controls: true,
        //自动播放属性,muted:静音播放
        muted: false,
        autoplay: true,
        //建议浏览器是否应在<video>加载元素后立即开始下载视频数据。
        preload: "auto",
        //设置视频播放器的显示宽度(以像素为单位)
        width: "800px",
        //设置视频播放器的显示高度(以像素为单位)
        height: "500px",
        // poster: 'https://static.shuxuejia.com/img/video_image.png', // 封面图片
        sources: [{
          src:"rtmp://58.200.131.2:1935/livetv/cctv3",
          type:'video/rtmp'
        }],
            
        playbackRates: [0.5, 1, 1.5, 2] //倍速播放
      }, function onPlayerReady() {
        Video.log('Your player is ready!'); // 比如: 播放量+1请求
        this.on('ended', function() {
          Video.log('Awww...over so soon?!');
        });
      });
      // this.myPlayer.src('rtmp://10.15.3.31:1935/live/openUrl/QUDplmM')
      // this.myPlayer.load('rtmp://10.15.3.31:1935/live/openUrl/QUDplmM')
        },
    beforeDestroy() {
      if (this.player) {
        this.player.dispose()
      }
    },
        
  }
</script>
<style scoped lang="scss">
.box{
    width:100%;
    height:100%;
    display:flex;
    align-items: center;
    justify-content: center;
    .video{
        margin:0 auto;
    }
}
</style>

2.方法二:ckplayer

由于本人已尝试过因flash原因导致不可用的情况,相关代码已删除,此处无截图,仅做文字描述,感兴趣者可自行搜索。

  • 第一步:官网下载ckplayer
  • 第二步:将下载好的文件夹解压后放入项目的static(静态资源文件夹)中
  • 第三步:在index.html中引入ckplayer.js文件
  • 第四步:创建播放视频的vue文件,代码如下:
<template>
  <div>
    <label>ckplayer播放器插件Vue使用Demo</label>
    <div id="video"></div>
  </div>
</template>
<script>
export default {
  name: 'ckplayerPlugin',
  data () {
    return {
    }
  },
  mounted: function(){
    // 挂载完成后进行
    var videoObject = {
                container: '#video', //容器的ID或className
                variable: 'player', //播放函数名称
                loaded: 'loadedHandler', //当播放器加载后执行的函数
                loop: true, //播放结束是否循环播放
                cktrack: 'static/ckplayer/material/srt.srt', //字幕文件
                poster: 'static/ckplayer/material/poster.jpg', //封面图片
                preview: { //预览图片
                    file: ['static/ckplayer/material/mydream_en1800_1010_01.png', 'static/ckplayer/material/mydream_en1800_1010_02.png'],
                    scale: 2
                },
                config: '', //指定配置函数
                debug: true, //是否开启调试模式
                drag: 'start', //拖动的属性
                seek: 0, //默认跳转的时间
                //广告部分开始
                adfront: 'http://×××w.ckplayer.com/yytf/swf/front001.swf,http://×××w.ckplayer.com/yytf/swf/front002.swf', //前置广告
                adfronttime: '15,15',
                adfrontlink: '',
                adpause: 'http://×××w.ckplayer.com/yytf/swf/pause001.swf,http://×××w.ckplayer.com/yytf/swf/pause002.swf',
                adpausetime: '5,5',
                adpauselink: '',
                adinsert: 'http://×××w.ckplayer.com/yytf/swf/insert001.swf,http://×××w.ckplayer.com/yytf/swf/insert002.swf',
                adinserttime: '10,10',
                adinsertlink: '',
                inserttime: '10,80',
                adend: 'http://×××w.ckplayer.com/yytf/swf/end001.swf,http://×××w.ckplayer.com/yytf/swf/end002.swf',
                adendtime: '15,15',
                adendlink: '',
                //广告部分结束
                promptSpot: [ //提示点
                    {
                        words: '提示点文字01',
                        time: 30
                    },
                    {
                        words: '提示点文字02',
                        time: 150
                    }
                ],
                video: [
                    ['http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4', 'video/mp4', '中文标清', 0],
                    ['http://img.ksbbs.com/asset/Mon_1703/d0897b4e9ddd9a5.mp4', 'video/mp4', '中文高清', 0],
                    ['http://img.ksbbs.com/asset/Mon_1703/eb048d7839442d0.mp4', 'video/mp4', '英文高清', 10],
                    ['http://img.ksbbs.com/asset/Mon_1703/d30e02a5626c066.mp4', 'video/mp4', '英文超清', 0]
                ]
            };
      // 定义一个对象
      var player = new ckplayer(videoObject);
  }
}
</script>
<style scoped>
  #video {
    width: 600px;
    height: 400px;
    margin: 0px auto;
  }
</style>

总结:经检验,以上两种方法加载均需要flash的支持,然而目前大众浏览器均已放弃flash,所以建议使用下方hls视频流播放;

三、vue加载hls视频流

1.index.html中

添加:

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

前言

以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。

<template>
  <div class="hls">
    <video id="video" muted></video>
  </div>
</template>
<script>
export default {
  name: 'hls-video',
  components: {
  },
  data() {
    return{
        video:null,
        hls:null
    }
  },
  props: {
    selectStdInfo:{
      type:Object,
      required:true
    }
  },
  watch:{
    // 视频弹窗时如果弹窗已存在,重新加载视频流
    "selectStdInfo.mourl":function(oldV,newV){
      if(newV!=oldV){
        this.initVideo()
      }
    }
  },
  mounted() {
    this.initVideo()
  },
  destroyed(){
    this.reset()
  },
  methods: {
        //组件销毁时,调用该方法,停止请求;detachMedia和stopLoad为hls官网方法
      reset(){
          this.hls.detachMedia(this.video)
          this.hls.stopLoad()   
      },
      //初始化video  
      initVideo () {       
          this.video = document.getElementById('video')
          // 浏览器是否支持hls 
          if(Hls.isSupported()) {
             //如果hls已存在,先清空
             if(this.hls){
                this.reset()
              }else{
                this.hls = new Hls()
              }
              //this.selectStdInfo.mourl为父组件传给该子组件的视频url
              this.hls.loadSource(this.selectStdInfo.mourl)
              this.hls.attachMedia(this.video)
              this.hls.on(Hls.Events.MANIFEST_PARSED,()=>{
                this.video.play()
              });
          }else if (video.canPlayType('http://kbs-dokdo.gscdn.com/dokdo_300/_definst_/dokdo_300.stream/playlist.m3u8')) {
            // 不支持hls ,支持苹果原生 
              this.video.src = ''
               this.video.addEventListener('loadedmetadata',function() {
                this.video.play()
           })
         }
      }
  },
}
</script>
<style scoped lang="scss">
.hls{
    width:100%;
    height:100%;
    display:flex;
    align-items: center;
    justify-content: center;
    #video{
    width:100%;
        margin:0 auto;
    }
}
</style>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章