南七星之家 发表于 2024-6-21 13:33:41

前端FLV视频直播解决方案

项目背景:

1. 背景给出一个地点,持续不停的推送flv视频流。
2.前端需要接收视频流,并探求合适的播放插件。
一开始:

着实用的是xgplayer(西瓜视频)。
官网地点:西瓜播放器
使用的是直播,flv的插件:西瓜播放器 | xgplayer-flv。
但是无法播放,现象就是一直loading;
厥后,查了很多多少资料,发现一个issue:
流数据正常下载,xgplayer-flv无法播放 · Issue #604 · bytedance/xgplayer · GitHub。
https://img-blog.csdnimg.cn/direct/3c3d28dc7aec47c792bd46a47abb0d92.png
和我环境一模一样,但是暂时没有什么解决方案。说明,此路不通。
柳暗花明:

找了很久,找到一个全能播放插件 —— Jessibuca。
官网地点:Jessibuca

如何使用:

前端如何使用?建议直接下载相关资源,静态引入。
需要下载三个资源,如下图:
https://img-blog.csdnimg.cn/direct/5dc3c2f4be0d49788323d5b843fe4d3c.png
怎么找到这三个资源?去官网的network里找找吧,不在多说。

vue中使用详情:

起首,上边的三个文件引入public。在index.html文件中只需要引入jessibuca.js。
<!--

public下的index.html 直接引入js文件

-->



....


<script src="<%= BASE_URL %>jessibuca.js"></script>





..... 然后,创建视频播放组件 LiveVideoPlay.vue:
<script>
export default {
name: "LiveVideoPlay",
props: {
    // 播放地址
    playUrl: {
      type: String,
      required: true,
    },
    // 目标domid
    id: {
      type: String,
      required: true,
    },
},
data() {
    return {
      player: null,
    };
},
methods: {
    // 初始化视频组件
    initPlayer() {
      if (Jessibuca) {
      this.player = new Jessibuca({
          container: document.getElementById(this.id), //jessibuca需要容器
          videoBuffer: 0.2, // 缓存时长
          isResize: false,
          loadingText: "疯狂加载中...",
          useMSE: true,
          useWCS: true,
          debug: true,
          background: "@/assets/icons/svg/no-video.svg",
          supportDblclickFullscreen: true,
          showBandwidth: true, // 显示网速
          operateBtns: {
            fullscreen: true,
            screenshot: true,
            play: true,
            audio: true,
          },
          forceNoOffscreen: true,
          isNotMute: false,
          timeout: 10,
      });
      //console.log("this.player ----- ", this.player, this.playUrl);
      this.player.play(this.playUrl);
      }
    },
},
beforeDestroy() {
    // 销毁视频
    if (this.player) {
      this.player.destroy();
      this.player = null;
    }
},
mounted() {
    this.initPlayer();
},
};
</script>
<template>
<div class="video-player-outer" :id="id"></div>
</template>
<style>
.video-player-outer {
width: 100%;
height: 100%;
}
</style>
最后,父组件中直接引用:
// 父组件中直接使用该组件

<script>
import LiveVideoPlay from "./LiveVideoPlay.vue";
export default {
    name: '',
    components: {
      LiveVideoPlay
    },
    data () {
      return {
            playUrl1: null,
            playUrl2: null,
            showV1: false,
            showV2: false,
      }
    },
    methods: {
      handlePlayVideo(v) {
      if (v == 1) {
      this.playUrl1 =
          "https://xxxxxx/live/02.live.flv";
      this.showV1 = true;
      } else if (v == 2) {
      this.playUrl2 =
          "https://xxxxxx/live/02.live.flv";
      this.showV2 = true;
      }
    },
    StopPlayVideo(v) {
      if (v == 1) {
      this.showV1 = false;
      } else if (v == 2) {
      this.showV2 = false;
      }
    },
    },
}

</script>

<template>

    <div class="box">
          <div class="video-box-item">
            <el-button @click="handlePlayVideo(1)">播放视频1</el-button>
            <el-button @click="StopPlayVideo(1)">停止视频1</el-button>
            <LiveVideoPlay v-if="showV1" :playUrl="playUrl1" id="v1" />
          </div>

          <div class="video-box-item">
            <el-button @click="handlePlayVideo(2)">播放视频2</el-button>
            <el-button @click="StopPlayVideo(2)">停止视频2</el-button>
            <LiveVideoPlay v-if="showV2" :playUrl="playUrl2" id="v2" />
          </div>
    </div>

</template> 如上,可以试一试本身的播放地点是否可以成功播放视频.如果你的需求不那么高,不考虑延迟,到这里基本就够了,不需要卷下去.
但是,如果你的要求比较高,又不想买jecibuca的收费版本,那么请继续往下看, 有更好的解决方案.

优中选优:

现在这个功能是做出来了,但是视频延迟的问题比较突出.比如,我控制摄像头旋转一下位置,在上述解决方案中,会明显发现摄像头触发旋转进而回传视频明显延迟.那怎么办? 如果你要求不高,那么上边的解决方案足够使用,但是如果要求低延迟,那么就不得不祭出另个大杀器了 - LiveQing.
官网地点: LivePlayer H5播放器 | 青柿视频流媒体服务解决方案
如何使用? vue2中大概分为这几步调(vue3+vite的可以参考官网):
1. 安装 Liveplayer:
npm install @liveqing/liveplayer 2. 安装 webpack 插件 copy-webpack-plugin
npm install copy-webpack-plugin@4.6.0 注意: 如果你的版本是vuecli4.0+, 那么以上这个版本就够用了.但是 如果你的vuecli5.0+, 你需要升级这个copywebpack-plugins的版本,比如 copy-webpack-plugin@11.0.0 .亲测有效,一定要注意!!!
3. 配置vue.config.js
/**vue.config.js   */

// *****注意 还是vuecli版本的问题
// *****如果你的vuelci4.0+就用下边这个配置

const CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports = {

    ...


    configureWebpack: (config) => {
      config.devtool = "source-map";
      config.output.libraryExport =
                      "default"; /* 解决import UMD打包文件时, 组件install方法执行报错的问题!! */



      // 增加配置如下主要是 plugins

      const plugins = [
          new CopyWebpackPlugin([
            {
            from: "node_modules/@liveqing/liveplayer/dist/component/crossdomain.xml",
            },
            {
            from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer.swf",
            },
            {
            from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer-lib.min.js",
            to: "livePlayer/",
            },
      ]),
    ];
      config.plugins.push(...plugins);

      
    }
},


    ...

}


// *****如果你的vuelci5.0+就用下边这个配置

const CopyWebpackPlugin = require("copy-webpack-plugin");


module.exports = {


    .....


    chainWebpack(config) {
      
      // 增加插件
      
      config.plugin('copy').use(CopyWebpackPlugin, [

         {
               patterns: [
            {
            from: "node_modules/@liveqing/liveplayer/dist/component/crossdomain.xml",
            },
            {
            from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer.swf",
            },
            {
            from: "node_modules/@liveqing/liveplayer/dist/component/liveplayer-lib.min.js",
            to: "livePlayer/",
            },
      ]
            }
      ])

      
    }
   


} 4. public中的index.html中引入js文件
https://img-blog.csdnimg.cn/direct/6e0d99ba4c534aeda3b735c14a05040a.png
5. 封装播放视频组件
<template>
<LivePlayer
    class="component-wrapper video-panel"
    :class="{ fullscreen: flag }"
    :videoUrl="options.url"
    :videoTitle="options.title"
    :poster="options.poster"
    :controls="options.controls"
    :autoplay="options.autoplay"
    :live="options.live"
    :hide-snapshot-button="options.hideSnapshot"
    :muted="options.muted"
    :fluent="options.fluent"
    :stretch="options.stretch"
    :aspect="options.aspect"
    :loading="options.loading"
    :hide-big-play-button="options.hideBigPlay"
    @fullscreen="onFullscreen"
>
    <slot></slot>
</LivePlayer>
</template>

<script>
import LivePlayer from "@liveqing/liveplayer";

export default {
name: "LiveVideoRtcPlayer",
components: {
    LivePlayer,
},
props: {
    params: {
      type: String,
    },
},
data() {
    return {
      flag: false,
    };
},
computed: {
    options() {
      return {
      // 播放地址
      url: this.params,
      // 视频标题
      title: "",
      // 视频封面图片
      poster: "",
      // 播放器控制栏
      controls: true,
      // 隐藏截图
      hideSnapshot: true,
      // 是否直播
      live: true,
      // 是否自动播放
      autoplay: true,
      // 是否静音
      muted: true,
      // 流畅模式
      fluent: true,
      // 是否拉伸
      stretch: true,
      // 全屏 - 适应div
      aspect: "fullscreen",
      // 指示加载状态
      loading: true,
      // 隐藏起播状态下的大播放按钮
      hideBigPlay: true,
      };
    },
},
created() {
    console.log("配置 ----- ", this.options);
},
beforeDestroy() {
    if (this.options) {
      this.options.url = "";
    }
    this.onExitFullscreen();
},
methods: {
    onExitFullscreen() {
      this.flag = false;
    },
    onFullscreen(status) {
      this.flag = status;
      if (!status) {
      this.onExitFullscreen();
      return;
      }
    },
},
};
</script>

<style lang="scss" scoped>
.component-wrapper.video-panel {
position: relative;
width: 100%;
height: 100%;

.video-wrapper .video-js {
    background-color: rgba(32, 46, 71, 0.6);

    .video-title {
      top: 4px;
      right: unset;
      left: 4px;
      padding: 4px 6px;
      max-width: 80%;
      font-size: 16px;
    }

    .video-control {
      position: absolute;
      top: 100%;
      left: 50%;
      transform: translate(-50%, -140%);
      margin-top: 0;
    }
}

&.fullscreen .video-wrapper .video-js {
    .video-title {
      top: 60px;
      right: unset;
      left: 20px;
      padding: 5px 8px 6px;
      background: rgba(4, 16, 37, 0.6);
      border-radius: 4px;
    }
}
}
</style>
6. 父组件中引用播放组件
<template>
<div id="app">
    <!-- 视频 -->
    <div class="video-box">
      <el-button @click="handlePlayVideo(1)">播放视频1</el-button>
      <el-button @click="StopPlayVideo(1)">停止视频1</el-button>
      <div class="video-box-item">
      <LiveVideoRtcPlayer v-if="showV1" :params="playUrl1" id="v1" />
      </div>
      <el-button @click="handlePlayVideo(2)">播放视频2</el-button>
      <el-button @click="StopPlayVideo(2)">停止视频2</el-button>
      <div class="video-box-item">
      <LiveVideoRtcPlayer v-if="showV2" :params="playUrl2" id="v2" />
      </div>
    </div>
</div>
</template>

<script>
//import Child from "./Child.vue";
//import LiveVideoPlay from "./LiveVideoPlay.vue";
import LiveVideoRtcPlayer from "./LiveVideoRtcPlayer.vue";
export default {
name: "App",
components: {
    //LiveVideoPlay,
    LiveVideoRtcPlayer,
},
data() {
    return {
      playUrl1: null,
      playUrl2: null,
      showV1: false,
      showV2: false,
    };
},
methods: {
    handlePlayVideo(v) {
      if (v == 1) {
      // this.playUrl1 =
      //   "https://xxxxxxxxxxxx/live/02.live.flv";
      this.playUrl1 =
          "webrtcs://xxxxxxxxxxxxx/live/index/api";
      this.showV1 = true;
      } else if (v == 2) {
      this.playUrl2 = 'xxxxx 播放地址';
      this.showV2 = true;
      }
    },
    StopPlayVideo(v) {
      if (v == 1) {
      this.showV1 = false;
      } else if (v == 2) {
      this.showV2 = false;
      }
    },
},
};
</script>

<style lang="scss" scoped>
#app {
height: 100%;
}

#app ::v-deep .box {
font-size: 30px;
}

.video-box {
width: 100%;
height: 600px;
overflow: hidden;

&-item {
    width: 300px;
    height: 400px;
    float: left;
    overflow: hidden;
    background-color: #f1f2f3;
    margin-left: 50px;
    position: relative;
}
}
</style>
<style lang="scss"></style>
测试一下,nice.
累了,就这样吧.

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 前端FLV视频直播解决方案