当前位置:   article > 正文

webRtc-streamer简单使用-备份

webrtc-streamer

公司业务需求,在前端实现海康摄像头的实时播放,参考文档资料后决定使用webrtc-streamer来实现rtsp流的播放,在此备份一下,也希望能够帮助到有需要的友友。

准备工具

1.这里使用的是webrtc-streamer来对rtsp流视频进行转码,从而实现前端界面的播放。因为开始接手项目的时候公司没有流媒体服务器,所以是在本地测试,对本地cpu有一定的压力。你也可以将webrtc打包到docker镜像里运行。

https://wws.lanzouy.com/inBMK08uv02h (webrtc-streamer链接)
  • 1

2.我这里使用的是videojs包,当然你也可以直接用原生的video标签进行播放。下面附上相关依赖。

{
  "name": "videojsdemo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "chokidar": "^3.5.3",
    "core-js": "^3.23.4",
    "video.js": "^7.18.1",
    "videojs-contrib-hls": "^5.15.0",
    "vue": "^2.6.14",
    "vue-baidu-map": "^0.21.22",
    "vue-router": "^3.5.1",
    "vue-webrtc": "^2.0.0",
    "vueui": "^0.1.4",
    "vuex": "^3.6.2"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-plugin-router": "~5.0.0",
    "@vue/cli-plugin-vuex": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "vue-template-compiler": "^2.6.14"
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

一、使用步骤

1.这是我封装的视频播放的组件,可以按照需求自行修改。

<template>
  <div>
    <el-row>
      <el-col :span="24">
        <!-- <map-video :showV="videoShow" :rtspIp="rtspIp"></map-video> -->
        <div style="height: 40vh">
          <!-- 
            this.hackReset = false;//销毁组件
            this.$nextTick(() => {
            this.hackReset = true;//重建组件
            });
          -->
          <video
            :id="videoID"
            class="video-js"
            style="object-fit: fill"
            controls
            autoplay
            autobuffer
            muted
            preload="auto"
          ></video>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import "video.js/dist/video-js.css";
import videojs from "video.js";
export default {
  name: "TanchengkjWebDialogCom",

  props: {
    videoID: {
      type: String,
      default() {
        return "videoID";
      },
    },
    rtspIp: {
      type: String,
      default() {
        return "";
      },
    },
    videoShow: {
      type: Boolean,
      default() {
        return false;
      },
    },
    videoPlayName: {
      type: String,
      default() {
        return "";
      },
    },
  },

  data() {
    return {
      dialogFromVisible: this.videoShow,
      inDate: "",
      t2: null,
      getUrl: localStorage.getItem("getUrl"),
      player: null,
      webRtcServer: null,
      webRtcList: [],
      playerList: [],
      videoSeting: {
        language: "zh-CN",
        autoplay: true, // true/false 播放器准备好之后,是否自动播放 【默认false】
        controls: true, // /false 是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制了。也就是说界面上不会出现任何控制按钮
        /* height: 100, // 视频容器的高度,字符串或数字 单位像素 比如: height:300 or height:‘300px‘
         width: 100, // 视频容器的宽度, 字符串或数字 单位像素*/
        loop: false, // /false 视频播放结束后,是否循环播放
        muted: true, // /false 是否静音
        poster: "", // 播放前显示的视频画面,播放开始之后自动移除。通常传入一个URL
        preload: "auto", // 预加载   ‘auto‘ 自动   ’metadata‘ 元数据信息 ,比如视频长度,尺寸等 ‘none‘ 不预加载任何数据,直到用户开始播放才开始下载
        bigPlayButton: true,
      },
    };
  },
  watch: {
    videoShow: {
      immediate: true,
      handler: function (value) {
        this.dialogFromVisible = value;
        if (value == false) {
          console.log("视频关闭了!");
          // this.playerList[0].pause();
          // this.webRtcList[0].webRtcServer.disconnect();
        } else {
          this.$forceUpdate();
          console.log("输出一下rtsp:", this.rtspIp);
          setTimeout(() => {
            this.getWebRtc();
          }, 1000);
        }
      },
    },
  },

  mounted() {
    let that = this;
    this.initNDate();
    let procedure1 = new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log("1执行crtWebRtc成功!");
        that.crtWebRtc();
        resolve();
      });
    });

    let procedure2 = new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log("2执行getvideo成功!");
        that.getVideo();
        resolve();
      });
    });

    let procedure3 = new Promise(function (resolve, reject) {
      setTimeout(function () {
        console.log("3执行getWebRtc成功!");
        that.getWebRtc();
        resolve();
      });
    });

    procedure1
      .then((data) => {
        return procedure2;
      })
      .then((data) => {
        return procedure3;
      });

    // console.log("mounted输出rtspip:", this.rtspIp);
    // console.log("mounted输出videoID:", this.videoID);
    // console.log("mounted输出getUrl:", this.getUrl);
  },
  created() {},

  methods: {
    /*设置当前系统时间*/
    initNDate: function () {
      this.t2 = setInterval(() => {
        this.inDate = new Date().toLocaleString();
      }, 1000);
    },

    getVideo() {
      let that = this;
      this.playerList[0] = videojs(
        this.videoID,
        this.videoSeting,
        function onPlayerReady() {
          videojs.log("Your player is ready!");
          this.on("loadstart", function () {
            console.log("开始请求数据 ");
          });
          this.on("progress", function () {
            console.log("正在请求数据 ");
          });
          this.on("loadedmetadata", function () {
            console.log("获取资源长度完成 ");
          });
          this.on("canplaythrough", function () {
            console.log("视频源数据加载完成");
          });
          this.on("waiting", function () {
            console.log("等待数据");
          });
          this.on("play", function () {
            console.log("视频开始播放");
          });
          this.on("playing", function () {
            console.log("视频播放中");
          });
          this.on("pause", function () {
            console.log("视频暂停播放");
            that.webRtcList[0].webRtcServer.disconnect();
          });
          this.on("ended", function () {
            console.log("视频播放结束");
          });
          this.on("error", function () {
            console.log("加载错误");
          });
          this.on("seeking", function () {
            console.log("视频跳转中");
          });
          this.on("seeked", function () {
            console.log("视频跳转结束");
          });
          this.on("ratechange", function () {
            console.log("播放速率改变");
          });
          this.on("timeupdate", function () {
            console.log("播放时长改变");
          });
          this.on("volumechange", function () {
            console.log("音量改变");
          });
          this.on("stalled", function () {
            console.log("网速异常");
          });
        }
      );
      this.playerList.push(this.player);
      console.log("playerList", this.playerList);
      console.log("id_", this.playerList[0].id_);
    },
    crtWebRtc() {
      console.log("webRtcList:", this.webRtcList);
      for (const item of this.webRtcList) {
        if (this.videoID == item.name) {
          return;
        }
      }
      console.log("进来了开始初始化webRtc模块:", this.videoID);
      this.webRtcServer = new WebRtcStreamer(
        this.videoID,
        // "http://192.168.1.166:8000"
        this.getUrl
      );
      let s = {};
      s.name = this.videoID;
      s.webRtcServer = this.webRtcServer;
      this.webRtcList.push(s);
      console.log("this.webrtc哈", this.webRtcList);
    },
    getWebRtc() {
      console.log("将rtspip传递给webRtcServer.connect:", this.rtspIp);
      console.log("打印:webrtclist", this.webRtcList);
      this.webRtcList[0].webRtcServer.connect(this.rtspIp);
      // for (const item of this.webRtcList) {
      //   if (this.videoID == item.name) {
      //     return;
      //   }
      //   item.webRtcServer.connect(this.rtspIp);
      // }
    },
  },
  beforeDestroy() {
    console.log("运行销毁前生命周期事件");
    // this.webRtcList[0].webRtcServer.disconnect();
    // if (this.player) {
    // this.playerList[0].dispose();
    // }
  },
};
</script>

<style scoped>
.lf20 {
  margin-left: 20px;
}

/* // 覆盖层元素增加可穿透点击事件 */
.el-dialog__wrapper {
  pointer-events: none;
}

/* // 弹窗层元素不可穿透点击事件(不影响弹窗层元素的点击事件) */
.el-dialog {
  pointer-events: auto;
}

.el-dialog__title {
  line-height: 24px !important;
  font-size: 15px !important;
  color: #303133;
}

.el-dialog__header {
  padding: 5px 5px 0px 5px !important;
  text-align: left;
}

.el-dialog__headerbtn {
  position: absolute;
  top: 5px !important;
  right: 5px !important;
  padding: 0;
  background: 0 0;
  border: none;
  outline: 0;
  cursor: pointer;
  font-size: 16px;
}

.el-dialog__body {
  padding: 2px !important;
  color: #606266;
  font-size: 14px;
  word-break: break-all;
  height: 40vh;
  overflow-y: auto;
}

.el-divider--horizontal {
  display: block;
  height: 1px;
  width: 100%;
  margin: 0px 0 !important;
}

.el-menu:hover {
  opacity: 1 !important;
}

.ve-line {
  margin-left: 10px;
  padding-top: 20px;
  color: #fff4fd;
  width: 540px !important;
}
.el-row {
  margin-bottom: 2px;
  &:last-child {
    margin-bottom: 0;
  }
}
.el-col {
  border-radius: 4px;
}
.bg-purple-dark {
  background: #99a9bf;
}
.bg-purple {
  background: #d3dce6;
}
.bg-purple-light {
  background: #e5e9f2;
}
.grid-content {
  border-radius: 4px;
  min-height: 36px;
  height: 230px;
}
.row-bg {
  background-color: #f9fafc;
}
.cell-v {
  display: flex;
  flex-direction: column;
  height: 30vh;
}
.player {
  height: 100%;
}
.bk-button-group {
  color: #00a0e9;
}

.video-js {
  width: 100%;
  height: 100%;
}

.video-js .vjs-big-play-button {
  top: 50%;
  left: 50%;
  margin-left: -1.5em;
  margin-top: -1em;
}
.vjs-loading-spinner:before,
.vjs-loading-spinner:after {
  content: "";
  position: absolute;
  margin: -6px;
  -webkit-box-sizing: inherit;
  box-sizing: inherit;
  width: inherit;
  height: inherit;
  border-radius: inherit;
  opacity: 1;
  border: inherit;
  border-color: transparent;
  border-top-color: white;
  display: none;
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388

二、使用步骤

###1.其实使用webrtc来实现rtsp流视频的播放很简单,只需要注意以下几点:
####1.首先是初始化webrtc服务
打开webrtc-streamer.exe我们可以看到,它这里监听的是8000端口
所以后续我们在初始化webrtcserver的时候需要将你运行项目的地址与8000端口拼接

这边的"video"是video标签的id,因为id是唯一标识

####2.初始化好了webrtc服务后是初始化video播放器了

methods: {
    playVideo() {
      this.webRtcServer.connect(this.rtspUrl);
      // 初始化播放器
      this.getVideo();
    },
    getVideo() {
      //this.videoSeting
      let that = this;
      this.player = videojs(
        "video",
        this.videoSeting,
        function onPlayerReady() {
          videojs.log("Your player is ready!");
          this.on("loadstart", function () {
            console.log("开始请求数据 ");
          });
          this.on("progress", function () {
            console.log("正在请求数据 ");
          });
          this.on("loadedmetadata", function () {
            console.log("获取资源长度完成 ");
          });
          this.on("canplaythrough", function () {
            console.log("视频源数据加载完成");
          });
          this.on("waiting", function () {
            console.log("等待数据");
          });
          this.on("play", function () {
            console.log("视频开始播放");
          });
          this.on("playing", function () {
            console.log("视频播放中");
          });
          this.on("pause", function () {
            console.log("视频暂停播放");
            that.webRtcServer.disconnect();
          });
          this.on("ended", function () {
            console.log("视频播放结束");
          });
          this.on("error", function () {
            console.log("加载错误");
          });
          this.on("seeking", function () {
            console.log("视频跳转中");
          });
          this.on("seeked", function () {
            console.log("视频跳转结束");
          });
          this.on("ratechange", function () {
            console.log("播放速率改变");
          });
          this.on("timeupdate", function () {
            console.log("播放时长改变");
          });
          this.on("volumechange", function () {
            console.log("音量改变");
          });
          this.on("stalled", function () {
            console.log("网速异常");
          });
        }
      );
    },
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67


这里的video同样指的是video播放器的id,与初始化播放器是一对一的关系
这里我将整个代码都贴上来吧,以免有友友看不太清楚

<template>
  <div class="container">
    <div class="control_1">
      <a>input http server:</a
      ><input type="text" v-model="httpServer" placeholder="请输入服务端地址" />
    </div>
    <div class="control_2">
      <a>input rtsp url:</a
      ><input type="text" v-model="rtspUrl" placeholder="请输入rtsp流地址" />
    </div>
    <button style="margin-top: 15px" @click="playVideo">
      准备好了点击播放视频
    </button>
    <div class="videoPlay">
      <video
        id="video"
        class="video-js"
        style="object-fit: fill; width: 500px; height: 500px"
        controls
        autoplay
        autobuffer
        muted
        preload="auto"
      ></video>
    </div>
  </div>
</template>

<script>
import "video.js/dist/video-js.css";
import videojs from "video.js";
export default {
  name: "TailwindCSSDaisyUIHomeView",

  data() {
    return {
      httpServer: "",
      rtspUrl: "",
      player: null,
      webRtcServer: null,
      videoSeting: {
        language: "zh-CN",
        autoplay: true, // true/false 播放器准备好之后,是否自动播放 【默认false】
        controls: true, // /false 是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制了。也就是说界面上不会出现任何控制按钮
        /* height: 100, // 视频容器的高度,字符串或数字 单位像素 比如: height:300 or height:‘300px‘
         width: 100, // 视频容器的宽度, 字符串或数字 单位像素*/
        loop: false, // /false 视频播放结束后,是否循环播放
        muted: true, // /false 是否静音
        poster: "", // 播放前显示的视频画面,播放开始之后自动移除。通常传入一个URL
        preload: "auto", // 预加载   ‘auto‘ 自动   ’metadata‘ 元数据信息 ,比如视频长度,尺寸等 ‘none‘ 不预加载任何数据,直到用户开始播放才开始下载
        bigPlayButton: true,
      },
    };
  },

  mounted() {
    var a = `${window.location.href}`;
    var b = a.split(":");
    this.httpServer = `${b[0]}:${b[1]}:8000/`;
    console.log("httpServer", this.httpServer);
    // 初始化webrec服务
    this.webRtcServer = new WebRtcStreamer("video", this.httpServer);
  },

  methods: {
    playVideo() {
      this.webRtcServer.connect(this.rtspUrl);
      // 初始化播放器
      this.getVideo();
    },
    getVideo() {
      //this.videoSeting
      let that = this;
      this.player = videojs(
        "video",
        this.videoSeting,
        function onPlayerReady() {
          videojs.log("Your player is ready!");
          this.on("loadstart", function () {
            console.log("开始请求数据 ");
          });
          this.on("progress", function () {
            console.log("正在请求数据 ");
          });
          this.on("loadedmetadata", function () {
            console.log("获取资源长度完成 ");
          });
          this.on("canplaythrough", function () {
            console.log("视频源数据加载完成");
          });
          this.on("waiting", function () {
            console.log("等待数据");
          });
          this.on("play", function () {
            console.log("视频开始播放");
          });
          this.on("playing", function () {
            console.log("视频播放中");
          });
          this.on("pause", function () {
            console.log("视频暂停播放");
            that.webRtcServer.disconnect();
          });
          this.on("ended", function () {
            console.log("视频播放结束");
          });
          this.on("error", function () {
            console.log("加载错误");
          });
          this.on("seeking", function () {
            console.log("视频跳转中");
          });
          this.on("seeked", function () {
            console.log("视频跳转结束");
          });
          this.on("ratechange", function () {
            console.log("播放速率改变");
          });
          this.on("timeupdate", function () {
            console.log("播放时长改变");
          });
          this.on("volumechange", function () {
            console.log("音量改变");
          });
          this.on("stalled", function () {
            console.log("网速异常");
          });
        }
      );
    },
  },
};
</script>

<style>
.control_1 {
  display: block;
  /* margin-top: 20px; */
}
.control_2 {
  display: block;
  margin-top: 15px;
}
.videoPlay {
  width: 500px;
  height: 500px;
  margin: 15px auto;
}
.video-js {
  width: 100%;
  height: 100%;
}

.video-js .vjs-big-play-button {
  top: 50%;
  left: 50%;
  margin-left: -1.5em;
  margin-top: -1em;
}
.vjs-loading-spinner:before,
.vjs-loading-spinner:after {
  content: "";
  position: absolute;
  margin: -6px;
  -webkit-box-sizing: inherit;
  box-sizing: inherit;
  width: inherit;
  height: inherit;
  border-radius: inherit;
  opacity: 1;
  border: inherit;
  border-color: transparent;
  border-top-color: white;
  display: none;
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177

这个案例是通过input的双向绑定原理,将当前项目的url与8000端口拼接,然后输入rtsp流点击播放进行播放。
成功截图

总结

第一次写,见谅
可能写得不太好
如果有啥问题,可以留言交流

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号