隨着多媒體技術和網絡通信技術的迅速發展,視頻監控技術在電力系統、電信行業、工業監控、工地、城市交通、水利系統、社區安防等領域得到越來越廣泛的應用。攝像頭直播視頻監控通過網絡直接連接,可達到的世界任何角落,並能夠通過控制雲臺、存儲視頻監控音視頻,對現場遠程運維,實現隨時隨地想看就看的安防需求。
背景需求
攝像機雲臺控制在攝像機當中很常見,攝像機能將當前狀態下雲臺的水平角度、傾斜角度和攝像機鏡頭焦距等位置參數存儲到設備中,需要時可以迅速調用這些參數並將雲臺和攝像頭調整至該位置。 攝像機只要支持Onvif協議進行和第三方軟件或設備對接,大部分都能進行遠程控制。EasyNVR支持Onvif協議的設備雲臺控制,能實現和設備的實時數據傳輸及控制。
今天主要介紹通過EasyNVR接口二次開發,將雲臺控制及實時直播功能集成在自己的原有的web業務系統上。
-
demo效果如下:
-
demo是通過vue-cli腳手架搭建起來,簡單說一下,目錄結構
-
對easy-player不瞭解的這是播放器插件地址可以參看(https://www.npmjs.com/package/easy-player)
-
這裏主要講解一下App.vue內容文件
<template>
<div id="app">
<!-- 測試鑑權 如果鑑權已關閉請忽略 -->
<div class="div-btn">
<el-button-group>
<el-button size="mini" type="success" @click="login">測試登錄</el-button>
<el-button size="mini" type="success" @click="loginout">測試退出</el-button>
<el-button size="mini" type="success" @click="testapi">測試鑑權</el-button>
</el-button-group>
</div>
<el-row>
<!-- 播放窗口組件 -->
<el-col :span="12">
<EasyPlayer :videoUrl="videoUrl" fluent autoplay live stretch></EasyPlayer>
<el-input v-model="input" placeholder="請輸入播放地址接口" size="mini"></el-input>
<p>列如:http://127.0.0.1:10800/api/v1/getchannelstream?channel=1&protocol=RTMP</p>
<el-button class="player-button" size="mini" type="success" @click="player">播放</el-button>
</el-col>
<!-- 雲臺控制組件 -->
<el-col :span="12">
<div class="control-box">
<!-- 雲臺控制按鈕列表 -->
<span @click="testControl('zoomin')"><i class="el-icon-circle-plus-outline"></i></span>
<span @click="testControl('up')"><i class="el-icon-arrow-up"></i></span>
<span @click="testControl('zoomout')"><i class="el-icon-remove-outline"></i></span>
<span @click="testControl('left')"><i class="el-icon-arrow-left"></i></span>
<span @click="testControl('stop')">停止</span>
<span @click="testControl('right')"><i class="el-icon-arrow-right"></i></span>
<span></span>
<span @click="testControl('down')"><i class="el-icon-arrow-down"></i></span>
<span></span>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
import md5 from "md5"; //引入md加密密碼傳給服務端,這裏默認是admin *修改在103行*
import EasyPlayer from "easy-player"
export default {
data() {
return {
videoUrl:'', // 這裏定義一個變量用來保存視頻流地址
input:'', // 接收用戶的接口地址
timer: 0, // 定時器用來保活接口
channels: '', // 保存接口地址通道地址
protocols: '' // 保存接口地址視頻類型
}
},
components:{
EasyPlayer
},
mounted() {},
methods: {
player() { // 當輸入完接口地址按下播放會執行這個函數
if(!this.input){
this.$message.error('請輸入接口地址!');
}else{
let strs = this.input.split('?')[1].split('&')
for (const iterator of strs) {
if (iterator.indexOf('channel') != -1) this.channels = parseInt(iterator.split('=')[1])
if (iterator.indexOf('protocol') != -1) this.protocols = iterator.split('=')[1]
}
this.play() //當player函數接收到可用的地址執行play函數
}
},
play() { //play函數會向服務端發送請求對應的通道及視頻類型
this.$axios.get('/api/v1/getchannelstream', {
params: {
channel: this.channels,
protocol: this.protocols
}
})
.then((response) => { //請求成功服務端會返回對應的通道的視頻流地址把返回的地址傳給之前定義videoUrl 就可以播放視頻但是視頻播放一會就會停止,需要保活接口下面創建一個定時器(注意:保活只是在按需的情況下使用)
this.videoUrl = response.data.EasyDarwin.Body.URL
this.timer = setInterval(() => { //當請求成功定時器打開每30秒向服端端發送一下請求告訴服務端客戶端需要播放視頻,不然服務端就會停止向設備端拉取視頻。
this.touchStream();
}, 30 * 1000);
if(!response.data.EasyDarwin.Body.URL)this.$message.error('播放失敗,檢查接口是否正確或者通道是否啓用!');
})
.catch((error) => {
let { status } = error.response
if (status == 401) Message.error('token值無效,請重新登錄')
});
},
touchStream() { //touchStream用來調取保活接口
this.$axios.get('/api/v1/touchchannelstream', {
params: {
channel: this.channels,
protocol: this.protocols
}
})
.then((response) => {
this.videoUrl = response.data.EasyDarwin.Body.URL
if(!response.data.EasyDarwin.Body.URL)this.$message.error('播放失敗!');
})
.catch((error) => {
let { status } = error.response
if (status == 401) Message.error('token值無效,請重新登錄')
});
},
login() { //測試登錄
this.$axios.get('/api/v1/login', {
params: {
username: "admin",
password: md5("admin")
}
})
.then((response) => {
this.$message({
message: '恭喜你,登錄成功!',
type: 'success'
});
})
.catch((error) => {
this.$message.error('用戶名或密碼錯誤,登錄失敗!');
});
},
loginout() { //測試推出
this.$axios.get('/api/v1/logout')
.then((response) => {
this.$message({
message: '成功退出!',
type: 'success'
});
})
.catch((error) => {
console.log(error)
});
},
testapi() { //測試接口鑑權是否生效
this.$axios.get('/api/v1/getchannelsconfig', {
params: {
start: 0,
limit: 1
}
})
.then((response) => {
this.$message({
message: '鑑權成功!',
type: 'success'
});
})
.catch((error) => {
this.$message.error('鑑權失敗!');
});
},
testControl(data) { // testControl裏的data是接收雲臺控制組件的裏按鈕傳遞的參數。
this.$axios.get('/api/v1/ptzcontrol', {// 調取雲臺接口地址
params: {
channel: this.channelNum, // 調取對應的設備通道地址
command: data // 調取雲臺接口的控制參數
}
})
.then((response) => {
console.log(response)
})
.catch((error) => {
console.log(error)
});
}
}
}
</script>
<style lang="scss">
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
// text-align: center;
color: #2c3e50;
}
.el-row, .div-btn{
max-width: 800px;
margin: auto;
}
.div-btn {
padding: 5px 0;
}
.el-col {
min-height: 300px;
// border: 1px pink solid
}
.el-input {
padding: 5px;
box-sizing: border-box;
}
.player-button {
margin: 5px;
width: 100%;
}
.control-box {
width: 180px;
height: 180px;
margin: 50px;
span {
display: inline-block;
text-align: center;
float: left;
width: 60px;
height: 60px;
padding: 5px;
border-radius: 50%;
box-sizing: border-box;
// border: 1px solid #ccc;
line-height: 50px;
cursor: pointer;
&:hover {
background-color: #67C23A;
border: none;
}
}
}
p {
font-size: 12px;
}
</style>
下載項目到本地到目錄下安裝demo需要的依賴
npm install
運行項目
npm run serve
打包
npm run build
注意:需要攝像頭支持雲臺控制。
EasyNVR部署架構
EasyNVR應用場景
EasyNVR在互聯網安防直播行業已有多年實戰經驗,通過各行業的市場檢驗已成爲一套便捷、安全、覆蓋範圍廣的成熟產品,結合硬件產品,服務於各行各業視頻基礎建設,同時提供二次開發接口便於企業集成到自己的業務系統中,打造專屬於自己的互聯網視頻監控平臺。
關於EasyNVR
EasyNVR是一款擁有完整、自主、可控知識產權,同時又能夠具備軟硬一體功能的安防互聯網化流媒體服務器,能夠通過簡單的網絡攝像機通道配置,將傳統監控行業裏面的高清網絡攝像機IP Camera、NVR等具有RTSP、Onvif協議輸出的設備接入到EasyNVR,EasyNVR能夠將這些視頻源的音視頻數據進行拉取,轉換爲RTMP/HLS,進行全平臺終端H5直播(Web、Android、iOS),並且EasyNVR能夠將視頻源的直播數據對接到第三方CDN網絡,實現互聯網級別的直播分發。詳情可訪問EasyNVR官網:http://www.easynvr.com
—本文轉自EasyNVR官方技術博客:https://blog.csdn.net/EasyNVR