Former-commit-id: 62d1aaf757dac6209361ca21539915e68de08d45
TangShanKaiPing
wanggang 6 years ago
parent f861b38146
commit 14fe0d9711

@ -15,22 +15,22 @@
</PackageReference>
<PackageReference Include="JWT" Version="5.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.1" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0-rc1.final" />
<PackageReference Include="Serilog.AspNetCore" Version="3.1.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="DotNetCore.NPOI" Version="1.2.2" />
<PackageReference Include="HtmlAgilityPack.NetCore" Version="1.5.0.1" />
<PackageReference Include="MailKit" Version="2.4.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="MailKit" Version="2.4.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.0.0-rc4" />
<PackageReference Include="System.Drawing.Common" Version="4.6.0" />
<PackageReference Include="System.Drawing.Common" Version="4.6.1" />
<PackageReference Include="System.Management" Version="4.6.0" />
<PackageReference Include="ValueInjecter" Version="3.2.0" />
<PackageReference Include="Flurl" Version="2.8.2" />

@ -12,10 +12,10 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.1" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client.Core" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.1.4" />
<PackageReference Include="SerialPortStream" Version="2.2.0" />
<PackageReference Include="NetCoreSerial" Version="1.3.2" />

@ -185,8 +185,7 @@
</div>
</div>
</div>
<template v-if="model.Product.Apis.length>0">
<!--接口-->
<template v-if="model.Name!=='摄像头'">
<div class="row" v-if="GetSimpleApis().length>0">
<div class="col-md-12">
<div class="card">
@ -196,39 +195,90 @@
</div>
</div>
</div>
<template v-if="model.Name!=='调色灯'">
<div class="=row" v-for="api in Enumerable.from(model.Product.Apis).orderBy('o=>o.Name')" v-if="api.Parameters.length>1">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{api.Name}}</h3>
</div>
<div class="card-body">
<form class="form-horizontal">
<input type="hidden" name="Number" :value="model.Number" />
<input type="hidden" name="Method" :value="api.Method" />
<div class="form-group" v-for="parameter in api.Parameters" v-if="parameter.Name!=='number'">
<label :for="parameter.Name">{{parameter.Description}}:</label>
<template v-if="model.Name==='网关'&&api.Name==='删掉制定设备'&&parameter.Name==='设备编号'">
<div class="=row" v-for="api in Enumerable.from(model.Product.Apis).orderBy('o=>o.Name')" v-if="api.Parameters.length>1">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{api.Name}}</h3>
</div>
<div class="card-body">
<form class="form-horizontal">
<input type="hidden" name="Number" :value="model.Number" />
<input type="hidden" name="Method" :value="api.Method" />
<div class="form-group" v-for="parameter in api.Parameters" v-if="parameter.Name!=='number'">
<label :for="parameter.Name">{{parameter.Description}}:</label>
<template v-if="model.Name==='网关'&&api.Name==='删掉制定设备'&&parameter.Name==='设备编号'">
</template>
<template v-else>
<template v-if="parameter.Type==='string'">
<input type="text" class="form-control" :name="parameter.Name" :value="GetDataValueByKey(parameter.Name)" />
</template>
<template v-else>
<template v-if="parameter.Type==='string'">
<input type="text" class="form-control" :name="parameter.Name" :value="GetDataValueByKey(parameter.Name)" />
</template>
<template v-else>
<input type="text" class="form-control" :name="parameter.Name" :value="GetDataValueByKey(parameter.Name)" />
</template>
<input type="text" class="form-control" :name="parameter.Name" :value="GetDataValueByKey(parameter.Name)" />
</template>
</template>
</div>
<div class="row">
<div class="col-sm-12">
<button class="btn btn-success">确定</button>
</div>
<div class="row">
<div class="col-sm-12">
<button class="btn btn-success">确定</button>
</div>
</div>
</form>
</div>
</form>
</div>
</div>
</div>
</template>
<template v-else-if="model.Name==='摄像头'">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{model.DisplayName}}</h3>
<input type="hidden" id="camera" :value="model.Number" />
<div class="card-tools">
<button class="btn btn-success" v-on:click="CallApi(model.Number,'/Onvif/StartPush')">开始推流</button>
<button class="btn btn-success" v-on:click="CallApi(model.Number,'/Onvif/StopPush')">停止推流</button>
</div>
</div>
<div style="max-width:100%;max-height:50%;margin:0;padding:0;background:#000;">
<video id="liveVideo" class="video" controls autoplay style="width:100%;max-width:100%;height:100%;"></video>
</div>
</div>
</div>
</div>
<div class="row" id="ptz">
<div class="col-md-12">
<div class="card" style="height:220px;">
<div class="card-header">
<h3 class="card-title"><img src="/images/ptz.png" />云台操作</h3>
</div>
<div class="card-body" style="height:178px;">
<table class="ptz" style="width:100%;">
<tr>
<td></td>
<td></td>
<td><img class="ajax camera" data-cmd="Up" :src="iotCenter+'/images/up.png'" /></td>
<td></td>
<td></td>
</tr>
<tr>
<td><img class="ajax camera" data-cmd="Zoomin" :src="iotCenter+'/images/zoomin.png'" /></td>
<td><img class="ajax camera" data-cmd="Left" :src="iotCenter+'/images/left.png'" /></td>
<td><img class="ajax camera" data-cmd="Stop" :src="iotCenter+'/images/stop.png'" /></td>
<td><img class="ajax camera" data-cmd="Right" :src="iotCenter+'/images/right.png'" /></td>
<td><img class="ajax camera" data-cmd="Zoomout" :src="iotCenter+'/images/zoomout.png'" /></td>
</tr>
<tr>
<td></td>
<td></td>
<td><img class="ajax camera" data-cmd="Down" :src="iotCenter+'/images/down.png'" /></td>
<td></td>
<td></td>
</tr>
</table>
</div>
</div>
</div>
</template>
</div>
</template>
</template>
</div>

@ -270,7 +270,7 @@
<div class="col-md-12">
<div class="card">
<select class="form-control" id="camera" v-on:change="CameraSelected" style="height:40px;">
<option v-for="c in GetDevices('摄像头')" :value="c.Number">{{c.DisplayName||c.Name}}</option>
<option v-for="c in GetDevices('摄像头')" :value="c.Number">{{c.DisplayName}}</option>
</select>
<div style="width:100%;height:180px;margin:0;padding:0;background:#000;">
<video id="liveVideo" class="video" controls autoplay style="width:100%;max-width:100%;height:100%;"></video>

@ -7,7 +7,7 @@
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup>
 <ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.0.1" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="wwwroot\**\*" />

@ -69,6 +69,9 @@ function onMessage(method, json, to, from) {
if ($('canvas#' + device.Number).length) {
UpdateChart(device.Number);
}
if ($('#camera').val() === device.Number && item.Name === '推流') {
UpdateCamera();
}
}
}
}

@ -106,7 +106,7 @@ methods = {
GetChartDevices() {
return Enumerable.from(this.model.Devices)
.where(function (o) { return o.Name === '温湿度传感器' || o.Name === 'PM2.5感应器' || o.Name === '光强检测器' || o.Name === '智能插座'; })
.orderBy('o=>o.ProductId')
.orderBy(function (o) { return o.Name;})
.toArray();
}
};
@ -130,6 +130,10 @@ function onMessage(method, json, to, from) {
if ($('canvas#' + device.Number).length) {
UpdateChart(device.Number);
}
if ($('#camera').val() === device.Number && item.Name === '推流') {
console.log('start update camera');
UpdateCamera();
}
}
}
}

@ -515,42 +515,45 @@ function playFlv(videoElement) {
$('#ptz').hide();
}
closePlayer(livePlayer);
try {
livePlayer = flvjs.createPlayer({
type: 'flv',
url: url,
isLive: true,
cors: true
}, {
enableWorker: true,
enableStashBuffer: false,
stashInitialSize: 1,
fixAudioTimestampGap: false
});
livePlayer.attachMediaElement(videoElement);
livePlayer.load();
livePlayer.volume = volume;
livePlayer.muted = muted;
timer = setInterval(function () {
console.log('.');
if (livePlayer.statisticsInfo.speed == 0) {
console.log('reload1');
clearInterval(timer);
playFlv(videoElement);
}
else if (decodedFrames && livePlayer.statisticsInfo.decodedFrames <= decodedFrames) {
console.log('reload2');
clearInterval(timer);
playFlv(videoElement);
}
else if (livePlayer.buffered.end(0) - livePlayer.currentTime > 1) {
console.log('reset currentTime');
livePlayer.currentTime = livePlayer.buffered.end(0) - 0.001;
}
decodedFrames = livePlayer.statisticsInfo.decodedFrames;
}, 10 * 1000);
} catch (e) {
console.log(e);
var push = Enumerable.from(device.Data).where(o => o.Name === '推流').firstOrDefault();
if (push && push.Value === '是') {
try {
livePlayer = flvjs.createPlayer({
type: 'flv',
url: url,
isLive: true,
cors: true
}, {
enableWorker: true,
enableStashBuffer: false,
stashInitialSize: 1,
fixAudioTimestampGap: false
});
livePlayer.attachMediaElement(videoElement);
livePlayer.load();
livePlayer.volume = volume;
livePlayer.muted = muted;
timer = setInterval(function () {
console.log('.');
if (livePlayer.statisticsInfo.speed == 0) {
console.log('reload1');
clearInterval(timer);
playFlv(videoElement);
}
else if (decodedFrames && livePlayer.statisticsInfo.decodedFrames <= decodedFrames) {
console.log('reload2');
clearInterval(timer);
playFlv(videoElement);
}
else if (livePlayer.buffered.end(0) - livePlayer.currentTime > 1) {
console.log('reset currentTime');
livePlayer.currentTime = livePlayer.buffered.end(0) - 0.001;
}
decodedFrames = livePlayer.statisticsInfo.decodedFrames;
}, 10 * 1000);
} catch (e) {
console.log(e);
}
}
}
}

@ -17,7 +17,7 @@ methods = {
|| this.model.Name.indexOf('插座') >= 0;
},
GetDevices() {
return Enumerable.from(this.model.Devices).orderBy('o=>o.DisplayOrder').orderBy('o=>o.Name').toArray();
return Enumerable.from(this.model.Devices).orderBy(function (o) { return o.DisplayOrder; }).orderBy(function (o) {return o.Name }).toArray();
},
GetDataValue(number, name) {
var device = Enumerable.from(this.model.Devices)

@ -66,7 +66,7 @@ namespace IoTNode.DeviceServices.Onvif
{
try
{
this.Remove(item);
this.StopPushToServer(item);
}
catch (Exception ex)
{
@ -139,7 +139,8 @@ namespace IoTNode.DeviceServices.Onvif
this.UpdateDevice(deviceRepo, device);
var fileName = $"ffmpeg-{Helper.Instance.GetRunTime()}{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "")}";
var file = Path.Combine(this._env.WebRootPath, fileName);
this.UpdateData(deviceRepo, device, device.CreateData("Push", "是", DeviceDataType.String, "推流"));
var pushValue = device.Data.FirstOrDefault(o => o.Name == "推流")?.Value ?? "是";
this.UpdateData(deviceRepo, device, device.CreateData("Push", pushValue, DeviceDataType.String, "推流"));
this.UpdateData(deviceRepo, device, device.CreateData("Record", "否", DeviceDataType.String, "录像"));
this.UpdateData(deviceRepo, device, device.CreateData("ffmpeg.file", file, DeviceDataType.String, "ffmpeg路径", hidden: true));
this.UpdateData(deviceRepo, device, device.CreateData("ffmpeg.args", this._cfg["ffmpeg.args"], DeviceDataType.String, "ffmpeg.args", hidden: true));
@ -253,7 +254,7 @@ namespace IoTNode.DeviceServices.Onvif
}
if (remove)
{
this.Remove(key);
this.StopPushToServer(key);
}
}
foreach (var camera in cameras)
@ -264,7 +265,7 @@ namespace IoTNode.DeviceServices.Onvif
{
if (camera.Data.Any(o => o.Key == "NeedAuth" && o.Value == "否") || camera.Data.Any(o => o.Key == "HasAuth" && o.Value == "是"))
{
this.Publish(camera);
this.StartPushToServer(camera);
}
}
}
@ -276,7 +277,7 @@ namespace IoTNode.DeviceServices.Onvif
}
}
private void Publish(Device camera)
private void StartPushToServer(Device camera)
{
try
{
@ -351,7 +352,7 @@ namespace IoTNode.DeviceServices.Onvif
}
}
public void Remove(string key)
public void StopPushToServer(string key)
{
(Device camera, Process local, Process remote) item;
if (this._list.TryRemove(key, out item))
@ -573,8 +574,16 @@ namespace IoTNode.DeviceServices.Onvif
{
var repo = scope.ServiceProvider.GetService<IRepository<Device>>();
var device = repo.Table().Include(o => o.Data).FirstOrDefault(o => o.Number == number);
var data = device.Data.FirstOrDefault(o => o.Key == "Push");
data.Value = "是";
if (device != null)
{
var data = device.Data.FirstOrDefault(o => o.Key == "Push");
if (data != null)
{
data.Value = "是";
this.UpdateData(repo, device, data);
this.StartPushToServer(device);
}
}
}
}
@ -584,8 +593,16 @@ namespace IoTNode.DeviceServices.Onvif
{
var repo = scope.ServiceProvider.GetService<IRepository<Device>>();
var device = repo.Table().Include(o => o.Data).FirstOrDefault(o => o.Number == number);
var data = device.Data.FirstOrDefault(o => o.Key == "Push");
data.Value = "否";
if (device != null)
{
var data = device.Data.FirstOrDefault(o => o.Key == "Push");
if (data != null)
{
data.Value = "否";
this.UpdateData(repo, device, data);
this.StopPushToServer(device.Number);
}
}
}
}

Loading…
Cancel
Save