视频播放组件实战【LivePlayer H5播放器】

2023-05-16

在公司项目开发中,有一个项目里面需要做一个视频播放的功能,播放方式是调用海康平台提供的接口获取流地址来进行视频的播放并且最重要的是需要支持flash。由于前端用的Vue,对比了几个,最后选择了LivePlayer H5播放器。

官网介绍:H5直播/点播播放器,使用简单,功能强大, 免费使用。

官网地址:https://www.liveqing.com/docs/manuals/LivePlayer.html
github源码地址:https://github.com/livegbs/GB28181-Server

因为官网只是做了介绍,并没有具体的详细API,可以参考github源码,如果还不能解决问题,可以在官网加官方QQ群,会有专业人员帮忙解答。

有如下特点:

  • 支持MP4播放;
  • 支持m3u8/HLS播放;
  • 支持HTTP-FLV/WS-FLV播放;
  • 支持RTMP播放;
  • 支持直播和点播播放;
  • 支持播放器快照截图;
  • 支持点播多清晰度播放;
  • 支持全屏或比例显示;
  • 自带的flash支持极速和流畅模式;
  • 自带的flash支持HTTP-FLV播放;
  • 自动检测IE浏览器兼容播放;
  • 支持自定义叠加层;v1.7.9

在这里插入图片描述
属性(Property)

  • video-url: 视频流地址 String default ‘’
  • video-title:视频右上角显示的标题 String default ‘’
  • poster:视频封面图片 String default ‘’
  • autoplay: 自动播放 Boolean default true
  • controls 显示播放器控制栏 Boolean default true
  • loop 是否循环播放 Boolean default false
  • live 是否直播, 标识要不要显示进度条 Boolean default false
  • alt 视频流地址没有指定情况下, 视频所在区域显示的文字, 相当于 html img 标签的 alt 属性 String default ‘无信号’
  • muted 是否静音 Boolean default false
  • aspect 视频显示区域的宽高比, fullscreen 即是全屏展示 String default ‘16:9’
  • loading 指示加载状态, 支持 sync 修饰符
  • fluent 流畅模式, Boolean default true
  • stretch 是否拉伸, Boolean default false
  • timeout m3u8 加载超时(秒) Number default 20
  • show-custom-button 是否在工具栏显示自定义按钮(极速/流畅, 拉伸/标准), Boolean default true
  • resolution 供选择的清晰度配置 String 如 “yh,fhd,hd,sd” ( 说明:yh:原始分辨率,fhd:超清,hd:高清,sd:标清,不配置则不启用,需要提供多清晰度源,比如原画源是test.m3u8,则hd源即为test_hd.m3u8 )
  • resolutiondefault 默认播放的清晰度 String “hd”
  • playback-rates 倍速列表, Array default [0.5, 1, 2, 3]
  • playback-rate 默认倍速, Number default 1
  • hasaudio HTTP-FLV播放时使用:是否有音频,传递该属性用于处理只有音频或只有视频的源 Boolean,默认不配置自动判断
  • hasvideo HTTP-FLV播放时使用:是否有视频,传递该属性用于处理只有音频或只有视频的源 Boolean,默认不配置自动判断

方法(Medthod)

  • play 播放
  • pause 暂停
  • paused 获取暂停状态
  • getCurrentTime 获取当前播放时间进度, 同步返回播放时间进度数据
  • snap 外部 API 方式获取快照, 快照获取成功后, 触发 snapOutside Event
  • getMuted 获取静音状态
  • setMuted 设置静音状态
  • isFullscreen v1.7.6 获取全屏状态
  • requestFullscreen v1.7.6 触发全屏, 需要放置到交互事件回调中调用, 如果已处在全屏状态, 则退出全屏
  • getVolume v1.7.7 获取音量
  • setVolumev1.7.7 设置音量, 0~1

事件(Event)

  • message m3u8 加载失败时触发通知消息, 参数: { type: ‘’, message: ‘’}
  • error 播放器出错回调, 参数: Error Object
  • ended 播放结束, 参数: 无
  • timeupdate 进度更新, 参数: 当前时间进度
  • pause 暂停, 参数: 当前时间进度
  • play 播放, 参数: 当前时间进度
  • snapOutside 外部快照回调, 参数: 快照 Base64 数据
  • snapInside 内部快照回调, 由控制栏快照按钮触发, 参数: 快照 Base64 数据

安装使用(Install)

一、安装:npm install @liveqing/liveplayer

二、编辑webpack.xxx.config.js:

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

......
    // copy js lib and swf files to dist dir
    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: 'js/'}
    ]),
......

注意:本地开发的配置文件和生产环境的都要配置。

三、引入依赖js

在index.html中引入:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<meta name="renderer" content="webkit">
		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
		<title>xxx</title>
	</head>
  ...
  <script type="text/javascript" src="./js/liveplayer-lib.min.js"></script>
  ...
	<body>
		...
	</body>
</html>

四、编辑 Vue 组件

......

import LivePlayer from '@liveqing/liveplayer'

......
  components: {
    LivePlayer
  }
......

<LivePlayer :videoUrl="videoUrl" fluent autoplay live stretch></LivePlayer>

实战:播放器组件化

<template>
  <div style="border:#a8cae5 1px solid;">
    <el-row >
      <el-col :span="5" style="height: 25px">
        窗口{{rowIdx*winNum + colIdx + 1}}{{cameraName}}
      </el-col>
      <el-col v-if="isShowTab" :span="19-winNum">
        <el-radio v-if="isShowTab" v-model="protocol" label="hls">HLS</el-radio>
        <el-radio v-if="isShowTab" v-model="protocol" label="rtmp">RTMP</el-radio>
      </el-col>
      <el-col v-if="isShowTab" :span="winNum">
        <el-button size="mini" @click="close">关闭</el-button>
      </el-col>
    </el-row>

    <LivePlayer :cameraId="cameraId"
                :video-url='videoUrl'
                :video-title="videoTitle"
                muted live loading stretch resolution='hd,sd'
                v-loading="bLoading"
                element-loading-background="#000"
                :loading.sync="bLoading"></LivePlayer>

    <div :id="showPTZ" v-if="isShowTab" style="position: absolute;z-index:9999;" :style="{top:ptzTop + '%'}">
      <div class="showPTZ left-panel-accordion-content  ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active" style="height: 0px; overflow: auto; display: block;" role="tabpanel" _mask_="1">
        <i :class="iconClass" @click="chgTabState"></i>
        <div class="ptz-panal-up">
          <div id="ptz-speed-container" class="ptz-panal-up-left">
            <div id="ptz-speed" class="ptz-speed"></div>
            <div id="ptz-speed-high" class="ptz-speed-high" style="height: 32.5px; top: 39.5px;"></div>
          </div>
          <div class="ptz-panal-up-right" >
            <span id="ptz-auto" class="ptz-auto direction" title="自动扫描"></span>
            <span @click="controlPtz('UP')" id="ptz-up" class="ptz-up direction" title="上移" ctrlcmd="UP"></span>
            <span @click="controlPtz('DOWN')" id="ptz-down" class="ptz-down direction" title="下移" ctrlcmd="DOWN"></span>
            <span @click="controlPtz('LEFT')" id="ptz-left" class="ptz-left direction" title="左移" ctrlcmd="LEFT"></span>
            <span @click="controlPtz('RIGHT')" id="ptz-right" class="ptz-right direction" title="右移" ctrlcmd="RIGHT"></span>
            <span @click="controlPtz('LEFT_UP')" id="ptz-up-left" class="ptz-up-left direction" title="左上移动" ctrlcmd="LEFT_UP"></span>
            <span @click="controlPtz('RIGHT_UP')" id="ptz-up-right" class="ptz-up-right direction" title="右上移动" ctrlcmd="RIGHT_UP"></span>
            <span @click="controlPtz('LEFT_DOWN')" id="ptz-down-left" class="ptz-down-left direction" title="左下移动" ctrlcmd="LEFT_DOWN"></span>
            <span @click="controlPtz('RIGHT_DOWN')" id="ptz-down-right" class="ptz-down-right direction" title="右下移动" ctrlcmd="RIGHT_DOWN"></span>
            <span @click="controlPtz('ZOOM_IN')" id="ptz-zoomin" class="ptz-zoomin ptz-up-right-btn" title="变大焦距" ctrlcmd="ZOOM_IN"><span class="icon"></span></span>
            <span @click="controlPtz('ZOOM_OUT')" id="ptz-zoomout" class="ptz-zoomout ptz-up-right-btn" title="变小焦距" ctrlcmd="ZOOM_OUT"><span class="icon"></span></span>
            <span @click="controlPtz('13')" id="ptz-focusin" class="ptz-focusin ptz-up-right-btn" title="前调焦点" ctrlcmd="13"><span class="icon"></span></span>
            <span @click="controlPtz('FOCUS_FAR')" id="ptz-focusout" class="ptz-focusout ptz-up-right-btn" title="后调焦点" ctrlcmd="FOCUS_FAR"><span class="icon"></span></span>
            <span @click="controlPtz('IRIS_ENLARGE')" id="ptz-irisout" class="ptz-irisout ptz-up-right-btn" title="扩大光圈" ctrlcmd="IRIS_ENLARGE"><span class="icon"></span></span>
            <span @click="controlPtz('IRIS_REDUCE')" id="ptz-irisin" class="ptz-irisin ptz-up-right-btn" title="缩小光圈" ctrlcmd="IRIS_REDUCE"><span class="icon"></span></span>
          </div>
          <!--          <div id="ptz-slider" class="ptz-slider" style="font-size: 11px !important; text-indent: 3px; top: 39.5px;" title="4">4</div>-->
        </div>
        <div class="loading-container" style="left: 0px; top: 0px; height: 110px; width: 218px;">
          <div class="loading-container-overlay"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import LivePlayer from '@liveqing/liveplayer'
  import { getPreviewURLs,controllerHik } from '../../../../api/zhgd/video/hikVideo.js'
  export default {
    name: 'myVideoPlayer',
    props: ['cameraId', 'videoUrl', 'videoTitle', 'cameraName', 'rowIdx', 'colIdx', 'winNum'],
    components: {
      LivePlayer
    },
    data() {
      return {
        showPTZ: 'showPTZ' + this.rowIdx + this.colIdx,
        iconClass: 'el-icon-d-arrow-right',
        ptzTop: 20,
        isShowTab: this.videoUrl !== '',
        protocol: 'hls',
        bLoading: false
        // ptzRight:50,
        // videoUrl: 'rtmp://58.200.131.2:1935/livetv/hunantv'
      }
    },
    watch: {
      protocol(val) {
        console.log(this.rowIdx + '---' + this.colIdx + val)
        const params = { t: Math.random(), code: this.cameraId, protocol: val, streamType: '1' };
        getPreviewURLs(params).then(data => {
          if (data.code === '0') {
            let purl = data.data.url;
            if (window.location.host.indexOf('2.2.2.2') === 0) {
              purl = data.data.url.replace('36.32.24.38', '2.2.2.2');
            }
            this.videoUrl = purl;
          }
        });
      }
    },
    methods: {
      chgTabState() {
        if (this.iconClass === 'el-icon-d-arrow-right') {
          $('#showPTZ' + this.rowIdx + this.colIdx + ' > .left-panel-accordion-content').css('width', '190px');
          // $('#showPTZ' + this.rowIdx + this.colIdx + ' > .showPTZ').css('right', '0px');
          this.iconClass = 'el-icon-d-arrow-left'
        } else {
          $('#showPTZ' + this.rowIdx + this.colIdx + ' > .left-panel-accordion-content ').css('width', '25px');
          // $('#showPTZ' + this.rowIdx + this.colIdx + ' > .showPTZ').css('right', '0px');
          this.iconClass = 'el-icon-d-arrow-right'
        }
      },
      close() {
        this.$emit('close');
      },
      controlPtz(code){
        var params={t:Math.random(),cameraId:this.cameraId,code:code,action:"0"};

        controllerHik(params).then(data => {
          if(data.code==0){
            window.setTimeout(() => {
              params.action = "1";
              controllerHik(params).then(data => {
                if(data.code==0){
                }else if(data.code=="0x01900050"){
                  alert("设备操作失败!");
                }else{
                  alert(data.msg);
                }
              });
            }, 2000);
          }else if(data.code=="0x01900050"){
            alert("设备操作失败!");
          }else{
            alert(data.msg);
          }
        });
      }
    },
    mounted() {
      $('#showPTZ' + this.rowIdx + this.colIdx + ' > .left-panel-accordion-content').css('width', '25px');
      $('#showPTZ' + this.rowIdx + this.colIdx + ' > .showPTZ').css('right', '0px');
    }
  }
</script>

<style scoped>
   .showPTZ{
    height: 110px !important;
    position: relative;
    overflow: hidden !important;
    display: block;
    /*background-color:rgba(43, 51, 63, 0.7)*/
    background-color:rgba(255, 255, 255, 0.7)
  }
  .ptz-panal-up {
    background-image: none;
    width: 160px;
    margin-left: 20px;
  }
   .ptz-panal-up-left {
    background-image: none;
  }
  .ptz-panal-up-right {
    background-image: none;
    top:8px;
  }
  .ptz-speed{
    background-image: none;
  }
  .left-panel-accordion-content {
    width: 190px;
  }
  .el-icon-d-arrow-left,.el-icon-d-arrow-right{
    position: absolute;
    top:40px;
    font-size: 25px;
    cursor: pointer;
    color: black;
  }
   .ptz-auto {
     background-position: -801px top;
   }
   .ptz-up {
     background-position: -549px top;
   }
   .ptz-down {
     background-position: -591px top;
   }
   .ptz-left {
     background-position: -758px top;
   }
   .ptz-right {
     background-position: -717px top;
   }
   .ptz-up-left {
     background-position: -841px top;
   }
   .ptz-up-right {
     background-position: -633px top;
   }
   .ptz-down-left {
     background-position: -883px top;
   }
   .ptz-down-right {
     background-position: -675px top;
   }
   .ptz-zoomin .icon {
     background-position: -1079px top;
   }
   .ptz-zoomout .icon {
     background-position: -959px top;
   }
   .ptz-focusin .icon {
     background-position: -1119px top;
   }
   .ptz-focusout .icon {
     background-position: -999px top;
   }
   .ptz-irisout .icon {
     background-position: -1159px top;
   }
   .ptz-irisin .icon {
     background-position: -1039px top;
   }
   /*>>> .video-wrapper .video-title {*/
   /*   max-width: 400px;*/
   /*  top:50px;*/
   /* }*/
</style>

说明:

  1. props: [‘cameraId’, ‘videoUrl’, ‘videoTitle’, ‘cameraName’, ‘rowIdx’, ‘colIdx’, ‘winNum’]
  • cameraId:为摄像头id,用于向后端发起请求调用海康接口获取流地址
  • videoUrl:播放视频的流地址
  • videoTitle:播放窗口右上角标题
  • cameraName:当前选中的摄像头名称
  • rowIdx,colIdx:播放窗口的横纵坐标(用于标识第几个播放窗口)
  • winNum:窗口序号
  1. 由于播放视频前需要取流,因为网络等问题可能会导致加载时间过长,默认不显示加载状态,加载样式可以自定义,关键代码:
    # 属性
    v-loading="bLoading"
    element-loading-background="#000"
    :loading.sync="bLoading"
    
    <div class="loading-container" style="left: 0px; top: 0px; height: 110px; width: 218px;">
    	<div class="loading-container-overlay"></div>
    </div>
    
    效果图:在这里插入图片描述
  2. 如果想验证取到的流地址是不是有问题,可以通过vlc这个专业的视频播放软件来验证。
    在这里插入图片描述

效果图:
在这里插入图片描述

  • hls流:对应标清
  • RTMP流:对应高清
  • 半透明云控制台上的图标可以点击,发送给海康接口,用来控制摄像头

调用该组件相关代码:

<el-row v-for="(rowData,rowIdx) in winRows" :key="rowData">
  <el-col v-for="(colData,colIdx) in rowData.cols" :key="colData.url" :span="colData.span" style="border: 1px #0fa2ff solid;">
       <my-video-player
         :cameraId="colData.cameraId"
         :videoUrl="colData.url"
         :videoTitle="colData.title"
         :rowIdx="rowIdx"
         :colIdx="colIdx"
         :winNum="winNum"
         @close="close(colData)"></my-video-player>
  </el-col>
</el-row>

winRows: [
	{ cols: [
	  { span: 24, url: '', title: '', cameraId: '' }
	] }
],
winNum: 1

#分屏方法
setWinNum(winNum) {
  const rows = Math.sqrt(winNum);
  this.winNum = rows;
  // 原来的组件数据存起来
  const oriArray = [];
  for (let i = 0; i < this.winRows.length; i++) {
    for (let j = 0; j < this.winRows[i].cols.length; j++) {
      if (this.winRows[i].cols[j].url !== '') {
        oriArray.push(this.winRows[i].cols[j])
      }
    }
  }
  // 创建一个新的winRows
  this.winRows = [];
  for (let i = 0; i < rows; i++) {
    this.winRows.push({ cols: [] })
  }
  for (let i = 0; i < this.winRows.length; i++) {
    for (let j = 0; j < rows; j++) {
      if (oriArray.length > 0) {
        this.winRows[i].cols.push({ span: 24 / rows, url: oriArray[0].url, title: oriArray[0].title, cameraId: oriArray[0].cameraId })
        oriArray.splice(0, 1);
      } else {
        this.winRows[i].cols.push({ span: 24 / rows, url: '', title: '', cameraId: '' })
      }
    }
  }
}
 
 #关闭播放窗口
 close(colData) {
   colData.url = ''
   colData.title = ''
   colData.cameraId = ''
 },  

#点击摄像头播放
playVideo(treeNode) {
  for (let i = 0; i < this.winRows.length; i++) {
    let isBreak = false;
    for (let j = 0; j < this.winRows[i].cols.length; j++) {
      if (this.winRows[i].cols[j].url === '') {
        const params = { t: Math.random(), code: treeNode.id, protocol: 'hls', streamType: '1' };
        getPreviewURLs(params).then(data => {
          if (data.code === '0') {
            let purl = data.data.url;
            if (window.location.host.indexOf('2.2.2.2') === 0) {
              purl = data.data.url.replace('36.32.24.38', '2.2.2.2');
            }
            const title = treeNode.lineName + '>' + treeNode.workareaName + '>' + treeNode.siteName;
            // + '>' + treeNode.title;
            this.winRows[i].cols[j].cameraId = treeNode.id;
            this.winRows[i].cols[j].url = purl;
            this.winRows[i].cols[j].title = title;
          }
        });
        isBreak = true;
        break;
      } else {
        continue;
      }
    }
    if (isBreak) {
      break;
    }
  }
},     

因为牵扯到多分屏的切换,切换后所有播放组件会重新加载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

视频播放组件实战【LivePlayer H5播放器】 的相关文章

  • 数组方式赋值字符串及字面值常量赋值字符串的区别

    c 43 43 实验笔记 数组赋值字符串时需要显示 39 0 39 xff0c 否则在某些时候会有问题 int main const char a 61 39 a 39 39 v 39 39 b 39 39 b 39 39 0 39 数组需
  • STL:: allocator之deallocate & destory的区别与联系

    c 43 43 中的allocator是标准库中的一个类 xff0c 负责内存分配管理 下面是 STL源码剖析 中一个简单allocator实现的部分源代码 xff1a deallocate xff1a template lt class
  • allocator简单实现

    allocator是c 43 43 标准库中用于管理内存的一个类 主要包括以下类方法 xff1a 代码如下 xff08 来源于 STL源码剖析 xff09 xff1a ifndef JJALLOC define JJALLOC includ
  • ROS2学习笔记(十一)-- ROS2 bag数据记录与回放

    简介 xff1a ROS2提供了ros2 bag命令 xff0c 可以记录指定主题的数据到文件中 xff0c 也可以将记录下的内容再发布出来 xff0c 相当于是数据的回放 xff0c 除了通过命令行的方式实现数据记录以外 xff0c 也可
  • Altium Designer 10 导出文件(PDF,gerber,BOM)

    作者 xff1a 卢老师 华清远见嵌入式学院讲师 5 导出原理图文档 GERBER 文件 xff0c BOM对于导出 PDF 文档 xff0c 多人分析时 xff0c 不能保证所有的电脑都安装有 AD10 软件 xff0c 这个也很有必要
  • 纯C++的Socket访问Http封装类

    纯C 43 43 的Socket访问Http封装类 1 项目中要使用c 43 43 43 43 来访问Web服务器 xff0c 从网上找了个C 43 43 的封装类 xff0c 其中调用了MFC xff0c 在VC2005上用能用 xff0
  • 一个C++解析HTML的库

    HTTP协议使用广泛 xff0c 相应的 xff0c C 43 43 在这块需求也开始增加 一个好的解析库可以达到事半功倍的效果 xff0c 在此贴出我的解析库的代码 xff0c 方便新手朋友们使用 hHttpParse h ifndef
  • Intel Realsense D435i SDK Install

    Intel Realsense D435i 0 引言1 参考2 Install3 Other 0 引言 自己买的还没到 xff0c 借的同学 xff0c 生怕给他搞坏了 1 参考 ref0 官方giahubref1 官方Installref
  • OBVP问题推导

    OBVP问题推导 0 引言1 推导2 code 0 引言 记录一下 时间紧张 xff0c 不整理了 xff0c 直接上草稿纸 一元四次方程求解参考博客 1 推导 2 code 代码完全按照推导书写 xff0c 包括变量的命令 span cl
  • CMakeLists中的add_definitions()函数

    CMakeLists中的add definitions函数 0 引言1 add definitions 2 应用 0 引言 其实这个函数在安装一些库的时候 xff0c 它的CMakeLists里面就有这样的函数 典型的就是opencv了 o
  • Intel Realsense D435i&L515 驱动安装

    Intel Realsense D435i amp L515 驱动安装 0 引言1 D435i amp L515固件更新1 1 D435i固件更新1 2 L515固件更新 2 Intel Realsense驱动安装3 ROS Wrapper
  • 位置编码Positional Encoding

    位置编码Positional Encoding 1 Transformers中的PE2 什么是Transformer位置编码2 1 表格型2 2 相对位置的关系 函数型 3 为什么可以表示相对距离 xff1f 4 其他参考 内容全来自于网络
  • vscode 调试 Python 代码

    vscode 调试 Python 代码 0 引言1 插件2 环境布置3 parser解析 0 引言 参考0参考1 1 插件 官方的python插件代码助手 xff0c 自动补全 xff1a 解释器选择 xff0c 在窗口右下角选择解释器 x
  • OpenCV 相机转换为 OpenGL 相机

    OpenCV 相机转换为 OpenGL 相机 0 引言1 预备知识和概述2 资源3 OpenCV和OpenGL中的图像坐标系统3 1 OpenCV H Z和OpenGL中的主轴3 2 齐次坐标和OpenGL中的归一化设备坐标 4 OpenC
  • 两轮差速小车循线控制原理分析

    硬件资料设定 xff1a 小车驱动来自于两个相同的电机 xff0c 转向依靠两轮差速实现 xff0c 小车前后左右安装超声波传感器 xff0c 前后各一个 xff0c 左右各两个 xff1b 功能目标 xff1a 假设小车左侧有墙壁 xff
  • ch06-Pytorch的正则化与归一化

    ch06 Pytorch的正则化与归一化 0 引言1 weight decay 和 dropout1 1 Regularization1 2 Dropout 2 Normalization2 1 Batch Normalization2 2
  • ch07-Pytorch的训练技巧

    ch07 Pytorch的训练技巧 0 引言1 模型保存与加载1 1 序列化与反序列化1 2 PyTorch 中的模型保存与加载1 3 模型的断点续训练 2 模型 Finetune2 1 Transfer Learning amp Mode
  • opencv-contrib-Python编译module 'cv2.cv2' has no attribute 'xfeatures2d'

    opencv contrib Python编译module 39 cv2 cv2 39 has no attribute 39 xfeatures2d 39 引言解决步骤一解决步骤二 引言 opencv contrib Python编译出现

随机推荐

  • find_package()函数

    find package函数 引言1 find package用法2 find package原理3 A required library with LAPACK API not found 错误解决4 添加findpackage查询路径
  • py安装文件时报错usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]

    py安装文件时报错usage setup py global opts cmd1 cmd1 opts cmd2 cmd2 opts 引言solved 引言 报错 xff1a python setup py fastentrypoints u
  • VScode单步调试

    VScode配置 0 快捷键1 安装clang2 VScodeDebug3 Cmake支持gdb调试的方法 0 快捷键 稍大工程在vscode下的调试参考该博客 Ctrl 43 打开默认终端 Ctrl 43 Shift 43 新建新的终端
  • 串口通信简介

    串口通信 串口通信是一种串行异步通信 xff0c 通信双方以字符帧作为数据传输单位 xff0c 字符帧按位依次传输 xff0c 每个位占固定的时间长度 两个字符帧之间的传输时间间隔可以是任意的 xff0c 即传输完一个字符帧之后 xff0c
  • ubuntu16.0 ROS(介绍EAI的YDLIDAR-X4激光雷达在ROS下使用方法)

    YDLIDAR X4激光雷达介绍 YDLIDAR X4激光雷达是深圳越登智能科技有限公司 xff08 YDLIDAR xff0c 这家公司属于EAI xff09 研发的一款 360 度二维测距产品 xff0c 本产品基于三角测距原理 xff
  • php使用http_build_query,parse_url,parse_str创建与解析url

    1 http build query http build query 可以创建urlencode之后的请求字符串 span class hljs keyword string span http build query mixed spa
  • 无人驾驶小车调试笔记(六)-- 车轮校准

    简介 xff1a 小车的动力完全来自于两个电机带动的车轮 xff0c 在理想状态下 xff0c 给两个电机同样的驱动参数 xff0c 两个车轮会以同样的转速带动小车直线行驶 xff0c 而实际情况是每个电机可能都会有个体差异 xff0c 也
  • Nginx HTTP详解

    正文 1 Nginx启动流程 2 HTTP 初始化 新连接建立时的行为 在上次博客的最后可以看到 xff0c 在ngx event accept方法建立连接的最后一步 xff0c 将会调用ngx listening t监听结构体的handl
  • 时钟周期,机器周期,指令周期的相互关系

    1 时钟周期 61 振荡周期 xff0c 名称不同而已 xff0c 都是等于单片机晶振频率的倒数 xff0c 如常见的外接12M晶振 xff0c 那它的时钟周期 61 1 12M 2 机器周期 xff1a 8051系列单片机的机器周期 61
  • 单片机的分频是什么意思?

    分频就是单片机的时钟频率 xff08 也就是晶振的震荡频率 xff09 F经过12分频 xff0c 变换成F 12的频率 简单的来说就是以整数倍降低频率 2分频就是分频前的频率除以2 xff1b 4分频就是分频前的频率除以4 比如 xff1
  • NMOS和PMOS管

    这里我先说一下我自己分辨MOS管的方法 对于NMOS我们看下图中的箭头 xff0c 都是远离源头 对于PMOS我们看箭头 xff0c 都是指向源头 P xff1a POSITIVE积极的寻找自己的起源 N xff1a NEGTIVE消极的远
  • 基本运算放大电路

    我先说明 下面的内容应该很多人都看到过 xff0c 但是我建议还是细看 xff0c 最好自己推一下 我就是这么做的 运算放大器工作原理综述 xff1a 运算放大器组成的电路五花八门 xff0c 令人眼花瞭乱 xff0c 在分析运算放大器工作
  • PCB板框的绘制——AD19

    pcb板框的绘制当然首先要切换到keep out 层才行 找到设置 xff0c 找到keep out 假如我们要绘制一个矩形的板框 xff0c 我们选择线径就可以 手动绘制一个矩形的板框 我们需要让我们的板子边框按照我们所绘制的走线来定义
  • 零基础自学STM32-野火——GPIO复习篇——使用绝对地址操作GPIO

    今天主要是复习一下 结合野火的 零基础开发指南 名字没记住大概是这个 先放一张结构图 存储器映射 xff08 初学重点 xff09 xff1a 我们的片内外设比如 xff1a Flash Sram Fsmc 以及挂在AHB 总线上的外设 x
  • Lcd1602——斌哥51

    最新修改时间2022 7 22 LCD1602 16代表显示16个字符 xff0c 2代表总共显示两行 芯片的工作电压是4 5 5 5v 工作电流2 0ma xff08 5V xff09 模块最佳工作电压5 0v 字符尺寸 xff1a 2
  • 无人驾驶小车调试笔记(七)-- 相机校准

    简介 xff1a 在第五节的内容中 xff0c 我们学习了使用rqt工具集观看摄像头视频流的方法 xff0c 细心的同学应该会发现camera node发布的视频数据中的图像有变形现象 xff0c 图像变形会导致直线不直 xff0c 部分区
  • Python实现MySql、SqlServer增删改查操作

    span class token keyword import span pymssql span class token keyword def span span class token function connection sql
  • ds1302——斌哥51

    以下内容分别借鉴了 清翔 51 xff0c 斌哥51 xff0c 以及CSDN 普通的不普通少年 内部结构 xff1a DS1302 包括时钟 日历寄存器和 31 字节 xff08 8 位 xff09 的数据暂存寄存器 xff0c 数据通信
  • AD添加LOGO

    先上原文链接 xff1a http www allchiphome com circuit pcb logo creator http www allchiphome com circuit pcb logo creator http ww
  • 视频播放组件实战【LivePlayer H5播放器】

    在公司项目开发中 xff0c 有一个项目里面需要做一个视频播放的功能 xff0c 播放方式是调用海康平台提供的接口获取流地址来进行视频的播放并且最重要的是需要支持flash 由于前端用的Vue xff0c 对比了几个 xff0c 最后选择了