Kaynağa Gözat

兼容rtmp格式的直播流-注意,浏览器必须开启flash才行

zjs_project 3 ay önce
ebeveyn
işleme
430f4af873

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1546 - 1090
package-lock.json


+ 3 - 0
package.json

@@ -10,6 +10,7 @@
   "dependencies": {
     "core-js": "^3.8.3",
     "cross-env": "^7.0.3",
+    "path": "^0.12.7",
     "vue": "^2.6.14",
     "vue-router": "^3.5.1",
     "vuex": "^3.6.2"
@@ -30,6 +31,8 @@
     "sass": "^1.86.3",
     "sass-loader": "^16.0.5",
     "style-resources-loader": "^1.4.1",
+    "video.js": "^5.1.9",
+    "videojs-flash": "^2.1.2",
     "vue-cli-plugin-style-resources-loader": "~0.1.5",
     "vue-template-compiler": "^2.6.14"
   },

+ 0 - 82
src/components/VideoPlayer.vue

@@ -1,82 +0,0 @@
-<template>
-    <div class="video-player">
-        <video ref="videoElement" controls autoplay class="video" muted="true" @error="onVideoError"></video>
-    </div>
-</template>
-
-<script>
-    import Hls from 'hls.js';
-    import Flv from 'flv.js';
-
-    export default {
-        props: {
-            videoUrl: {
-                type: String,
-                required: true,
-            },
-            videoType: {
-                type: String,
-                default: 'hls', // 'hls' or 'flv'
-            },
-        },
-        mounted() {
-            this.initPlayer();
-        },
-        beforeDestroy() {
-            this.destroyPlayer();
-        },
-        methods: {
-            initPlayer() {
-                const video = this.$refs.videoElement;
-
-                if (this.videoType === 'hls' && Hls.isSupported()) {
-                    const hls = new Hls();
-                    hls.loadSource(this.videoUrl);
-                    hls.attachMedia(video);
-                    hls.on(Hls.Events.MANIFEST_PARSED, () => {
-                        video.play();
-                    });
-                } else if (this.videoType === 'flv' && Flv.isSupported()) {
-                    const flvPlayer = Flv.createPlayer({
-                        type: 'flv',
-                        url: this.videoUrl,
-                    });
-                    flvPlayer.attachMediaElement(video);
-                    flvPlayer.load();
-                    flvPlayer.play();
-                } else {
-                    console.error('不支持的播放格式');
-                }
-            },
-            destroyPlayer() {
-                const video = this.$refs.videoElement;
-                if (Hls.isSupported()) {
-                    Hls.destroy();
-                }
-                if (Flv.isSupported()) {
-                    Flv.destroy();
-                }
-            },
-            onVideoError(e) {
-                console.error('视频播放错误:', e);
-            },
-        },
-    };
-</script>
-
-<style scoped>
-    .video-player {
-        width: 100%;
-        height: 100%;
-        background: #000;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-    }
-
-    .video {
-        width: 100%;
-        height: 100%;
-        object-fit: cover;
-    }
-</style>

+ 151 - 0
src/components/VideoPlayerComponent.vue

@@ -0,0 +1,151 @@
+<template>
+    <div class="video-player">
+        <!-- <video ref="videoElement" class="video video-js vjs-default-skin" controls autoplay muted="true"
+            @error="onVideoError" data-setup='{}'></video> -->
+        <!-- <videoPlayer v-show="videoType == 'rtmp'" :options="videoOptions" class="video videoPlayer" :playsinline="true" /> -->
+        <!-- <video v-show="videoType != 'rtmp'" ref="videoElement" controls autoplay class="video" muted="true" @error="onVideoError"></video> -->
+        <video ref="videoElement" controls autoplay class="video video-js vjs-default-skin" muted="true" @error="onVideoError" data-setup='{}'></video>
+    </div>
+</template>
+
+<script>
+    import Hls from 'hls.js';
+    import Flv from 'flv.js';
+
+    import videojs from 'video.js';
+    // import 'video.js/dist/video-js.css';
+    // import 'vue-video-player/src/custom-theme.css'
+    // import { videoPlayer } from 'vue-video-player'
+    import 'videojs-flash';
+    // console.warn("****videoPlayer1**",videoPlayer)
+    export default {
+        props: {
+            videoUrl: {
+                type: String,
+                required: true,
+            },
+            videoType: {
+                type: String,
+                default: 'hls', // 'hls' or 'flv'
+            },
+        },
+        // components: {
+        //     videoPlayer,
+        // },
+        data() {
+            return {
+                videoSrc: '',
+                // 视频播放
+                videoOptions: {
+                    // playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
+                    autoplay: true, //如果true,浏览器准备好时开始回放。
+                    muted: true, // 默认情况下将会消除任何音频。
+                    loop: true, // 导致视频一结束就重新开始。
+                    volume:0,
+                    preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
+                    language: 'zh-CN',
+                    aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
+                    techOrder: ['flash'], // 兼容顺序
+                    sources: [{
+                        // 流配置,数组形式,会根据兼容顺序自动切换
+                        type: 'rtmp/mp4',
+                        // src: 'rtmp://36.150.174.132:57935/oss/eHh4eFNfMjQ0ODQ1YmU5MTNkOjg1NTc5NTI2NDAwODI0ODUyODc?deviceId=xxxxS_244845be913d&expireTime=1744858930&playType=0', //拉流url
+                        src:'rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp'
+                    }],
+                    poster: '', //你的封面地址
+                    // width: document.documentElement.clientWidth,
+                    notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
+                    controls:false,
+                    // flash: {
+                    //     swf: '/node_modules/videojs-swf/dist/video-js.swf'
+                    // }
+                    // controlBar: {
+                    //     timeDivider: true,
+                    //     durationDisplay: true,
+                    //     remainingTimeDisplay: false,
+                    //     fullscreenToggle: true, //全屏按钮
+                    // },
+                },
+            }
+        },
+        
+        mounted() {
+            this.initPlayer();
+        },
+        beforeDestroy() {
+            this.destroyPlayer();
+        },
+        methods: {
+            initPlayer() {
+                const video = this.$refs.videoElement;
+
+                if (this.videoType === 'hls' && Hls.isSupported()) {
+                    const hls = new Hls();
+                    hls.loadSource(this.videoUrl);
+                    hls.attachMedia(video);
+                    hls.on(Hls.Events.MANIFEST_PARSED, () => {
+                        video.play();
+                    });
+                } else if (this.videoType === 'flv' && Flv.isSupported()) {
+                    const flvPlayer = Flv.createPlayer({
+                        type: 'flv',
+                        url: this.videoUrl,
+                    });
+                    flvPlayer.attachMediaElement(video);
+                    flvPlayer.load();
+                    flvPlayer.play();
+                } else if (this.videoType === 'rtmp') {
+                    // this.videoOptions.sources[0].src = this.videoUrl;
+                    videojs(video, {
+                        // autoplay: true, //如果true,浏览器准备好时开始回放。
+                        // muted: true, // 默认情况下将会消除任何音频。
+                        // loop: true, // 导致视频一结束就重新开始。
+                        // volume:0,
+                        techOrder: ['flash'],
+                        sources: [{
+                            // src: this.videoUrl,
+                            src:'rtmp://ns8.indexforce.com/home/mystream',
+                            type: 'rtmp'
+                        }],
+                        notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
+                        controls:false,
+                    });
+                } else {
+                    console.error('不支持的播放格式');
+                }
+            },
+            destroyPlayer() {
+                const video = this.$refs.videoElement;
+                if (this.videoType === 'hls' && Hls.isSupported()) {
+                    Hls.destroy();
+                }
+                if (this.videoType === 'flv' && Flv.isSupported()) {
+                    Flv.destroy();
+                }
+                if (this.videoType === 'rtmp') {
+                    videojs(video).dispose();
+                }
+            },
+            onVideoError(e) {
+                console.error('视频播放错误:', e);
+            },
+        },
+    };
+</script>
+
+<style scoped>
+    .video-player {
+        width: 100%;
+        height: 100vh;
+        background: #000;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+
+    .video {
+        width: 100%;
+        height: 100%;
+        object-fit: cover;
+    }
+</style>

+ 4 - 1
src/main.js

@@ -15,11 +15,14 @@ import App from './App.vue'
 import axios from 'axios';
 import router from './router'
 import store from './store'
+// import VideoPlayer from 'vue-video-player'
 import "./assets/iconfont.css" //引用公共icon库
 window.axios = axios;
 Vue.prototype.axios = axios;
 Vue.config.productionTip = false
-
+require('video.js/dist/video-js.css')
+// require('vue-video-player/src/custom-theme.css')
+// Vue.use(VideoPlayer)
 
 
 new Vue({

+ 7 - 5
src/views/HomeView.vue

@@ -2,29 +2,31 @@
     <div class="home">
         <!-- <img alt="Vue logo" src="../assets/logo.png">
         <HelloWorld msg="Welcome to Your Vue.js App"/> -->
-        <VideoPlayer :videoUrl="videoUrl" :videoType="videoType" />
+        <VideoPlayerComponent :videoUrl="videoUrl" :videoType="videoType" />
     </div>
 </template>
 
 <script>
     // @ is an alias to /src
     // import HelloWorld from '@/components/HelloWorld.vue'
-    import VideoPlayer from '@/components/VideoPlayer.vue';
+    import VideoPlayerComponent from '@/components/VideoPlayerComponent.vue';
     import requestConfig from '@/utils/requestConfig';
     export default {
         name: 'HomeView',
         components: {
             // HelloWorld,
-            VideoPlayer
+            VideoPlayerComponent
         },
         data() {
             return {
                 // https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
-                videoUrl: 'https://gcalic.v.myalicdn.com/gc/zyqcdx01_1/index.m3u8', // HLS 流地址
-                videoType: 'hls', // 或 'flv'
+                // videoUrl: 'https://gcalic.v.myalicdn.com/gc/zyqcdx01_1/index.m3u8', // HLS 流地址
+                // videoType: 'hls', // 或 'flv'
                 // 快手直播里面的
                 // videoUrl: 'https://ws-origin.pull.yximgs.com/gifshow/kwai_actL_ksle_20250411142108_GwU_strL_hd2000.flv?wsTime=67fa1bac&wsSecret=c09f848b129c9e352a4eab5ce2e06a80&stat=HKoB%2BwNN2oCYt7Rc2VlNANkgzdjg%2BiPBuC2zPQcpCqA6tJusJ0cQ%2BhKEfVoBjqV7&tsc=origin&oidc=watchmen&sidc=2062&no_script=1&srcStrm=lytuRPfcqgM&fd=0&ss=s20&tfc_buyer=0&kabr_spts=-5000', // HLS 流地址
                 // videoType: 'flv', // 或 'flv'
+                videoUrl: 'rtmp://36.150.174.132:57935/oss/eHh4eFNfMjQ0ODQ1YmU5MTNkOjg1NTc5NTI2NDAwODI0ODUyODc?deviceId=xxxxS_244845be913d&expireTime=1744858930&playType=0', // HLS 流地址
+                videoType: 'rtmp', // 或 'flv'
             };
         },
         mounted() {

+ 17 - 9
vue.config.js

@@ -1,11 +1,19 @@
-const { defineConfig } = require('@vue/cli-service')
+const {
+    defineConfig
+} = require('@vue/cli-service')
+// const path = require('path');
 module.exports = defineConfig({
-  transpileDependencies: true,
-lintOnSave: false, // 禁用 ESLint 检查
-  pluginOptions: {
-    'style-resources-loader': {
-      preProcessor: 'scss',
-      patterns: []
+    transpileDependencies: true,
+    lintOnSave: false, // 禁用 ESLint 检查
+    pluginOptions: {
+        'style-resources-loader': {
+            preProcessor: 'scss',
+            patterns: []
+        }
     }
-  }
-})
+    // configureWebpack: {
+    //     resolve: {
+    //       modules: [path.resolve(__dirname, 'node_modules'), 'node_modules'],
+    //     },
+    // },
+})