Former-commit-id: 95c16b694bad44ea71a9b67c722cda5f3c2db3ff
TangShanKaiPing
wanggang 6 years ago
parent 56d56bec7b
commit 288551c6e2

@ -12,10 +12,11 @@ namespace ApiGateway
gateway = new Gateway();
gateway.HttpOptions(o =>
{
o.Port = 80;//http://localhost/__system/bumblebee/routes.html
o.Port = 80;
o.LogToConsole = true;
o.LogLevel = BeetleX.EventArgs.LogType.Error;
});
Console.WriteLine("http://localhost/__system/bumblebee/routes.html");
gateway.Open();
gateway.LoadPlugin(typeof(Bumblebee.Configuration.Management).Assembly);
Console.Read();

@ -151,6 +151,7 @@ namespace Infrastructure.Web
o.SupportedUICultures = supportedCultures;
});
this.AddAuthentication(services);
//services.AddAuthorization();
this.AddSwagger(services);
services.AddDistributedMemoryCache();
services.AddSession(options =>

@ -273,7 +273,7 @@ namespace IoTCenter.Controllers
var fileds = String.Join(',', keys);
if (!string.IsNullOrEmpty(fileds))
{
var query = $"select {fileds} from {measurementName} where time>now()-{time} and DeviceNumber = '{device.Number}' limit 10000";
var query = $"select {fileds} from {measurementName} where time>now() - {time} and DeviceNumber = '{device.Number}' limit 10000";
var result = client.ReadAsync<DynamicInfluxRow>(dbName, query).Result;
var rows = result.Results.FirstOrDefault()?
.Series.FirstOrDefault()?

@ -280,7 +280,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}}</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%;" v-on:volumechange="VolumeChange($event)"></video>

@ -1,7 +1,7 @@
//
isDebug = true;
useSignalR = true;
templateUrl = baseUrl + '/App/GetTemplate?number=' + new URI().search(true).number;
templateUrl = null;// baseUrl + '/App/GetTemplate?number=' + new URI().search(true).number;
dataUrl = baseUrl + '/App/GetNode?number=' + new URI().search(true).number;
data = function data() {
return {

@ -473,7 +473,7 @@ function UpdateCamera() {
var number = $('#camera').val();
var video = document.getElementById("liveVideo");
if (number && video) {
if (flvjs.isSupported) {
if (flvjs.isSupported()) {
if(isApp&&!isAndroid)
{
playHls(video);
@ -489,11 +489,11 @@ function UpdateCamera() {
}
function playHls(video) {
var number = $('#camera').val();
var device = vm.model.Devices
? Enumerable.from(vm.model.Devices).where(function (o) { return o.Number === number; }).firstOrDefault()
var device = vm.model.devices
? Enumerable.from(vm.model.devices).where(function (o) { return o.number === number; }).firstOrDefault()
: vm.model;
if (device) {
var name = isApp ? "子码流hls" : "主码流hls";
var name = "hls";
var data = Enumerable.from(device.data).where(o => o.name === name).firstOrDefault();
if (data) {
var url = data.value;
@ -511,10 +511,10 @@ function playHls(video) {
function playFlv(videoElement) {
var number = $('#camera').val();
if (number) {
var device = vm.model.Devices
? Enumerable.from(vm.model.Devices).where(function (o) { return o.Number === number; }).firstOrDefault()
var device = vm.model.devices
? Enumerable.from(vm.model.devices).where(function (o) { return o.number === number; }).firstOrDefault()
: vm.model;
var name = isApp ? "子码流flv" : "主码流flv";
var name = "flv";
var data = Enumerable.from(device.data).where(o => o.name === name).firstOrDefault();
if (data) {
var url = data.value;

@ -16,21 +16,12 @@ namespace IoTNode.Controllers
this._deviceService = deviceService;
}
[HttpGet, Route("/[controller]/[action]"), SwaggerOperation("")]
public ApiResponse MainScreenShot([SwaggerParameter("设备编号")]string number)
[HttpGet, Route("/[controller]/[action]"), SwaggerOperation("")]
public ApiResponse ScreenShot([SwaggerParameter("设备编号")]string number)
{
return this.AsyncAction(() =>
{
this._deviceService.MainScreenShot(number);
});
}
[HttpGet, Route("/[controller]/[action]"), SwaggerOperation("")]
public ApiResponse SubScreenShot([SwaggerParameter("设备编号")]string number)
{
return this.AsyncAction(() =>
{
this._deviceService.SubScreenShot(number);
this._deviceService.ScreenShot(number);
});
}

@ -21,14 +21,10 @@ namespace IoTNode.DeviceServices.Onvif
public string PTZAddress { get; set; }
public bool Ptz3DZoomSupport { get; set; }
public List<Profile> Profiles { get; set; } = new List<Profile>();
public string MainStreamUriXml { get; set; }
public string MainSnapshotUriXml { get; set; }
public string SubStreamUriXml { get; set; }
public string SubSnapshotUriXml { get; set; }
public string MainStreamUri { get; set; }
public string SubStreamUri { get; set; }
public string MainSnapshotUri { get; set; }
public string SubSnapshotUri { get; set; }
public string StreamUriXml { get; set; }
public string SnapshotUriXml { get; set; }
public string StreamUri { get; private set; }
public string SnapshotUri { get; private set; }
public void ParseDiscovery()
{
@ -75,7 +71,6 @@ namespace IoTNode.DeviceServices.Onvif
{
resolution = videoEncoderConfiguration.Elements().FirstOrDefault(o => o.Name.LocalName == "Resolution");
}
//profile.Encoding = videoEncoderConfiguration.Elements().FirstOrDefault(o => o.Name.LocalName == "Encoding").Value;
if (condition)
{
profile.Width = Convert.ToInt32(resolution.Attribute("width").Value);
@ -92,14 +87,12 @@ namespace IoTNode.DeviceServices.Onvif
public void ParseStreamUri()
{
this.MainStreamUri = WebUtility.HtmlDecode(this.RegexMatch(this.MainStreamUriXml, @"[^<>]*", @"<tt:Uri>", @"</tt:Uri>"));
this.SubStreamUri = WebUtility.HtmlDecode(this.RegexMatch(this.SubStreamUriXml, @"[^<>]*", @"<tt:Uri>", @"</tt:Uri>"));
this.StreamUri = WebUtility.HtmlDecode(this.RegexMatch(this.StreamUriXml, @"[^<>]*", @"<tt:Uri>", @"</tt:Uri>"));
}
public void ParseSnapshotUri()
{
this.MainSnapshotUri = WebUtility.HtmlDecode(this.RegexMatch(this.MainSnapshotUriXml, @"[^<>]*", @"<tt:Uri>", @"</tt:Uri>"));
this.SubSnapshotUri = WebUtility.HtmlDecode(this.RegexMatch(this.SubSnapshotUriXml, @"[^<>]*", @"<tt:Uri>", @"</tt:Uri>"));
this.SnapshotUri = WebUtility.HtmlDecode(this.RegexMatch(this.SnapshotUriXml, @"[^<>]*", @"<tt:Uri>", @"</tt:Uri>"));
}
private string RegexMatch(string input, string pattern, string prefix, string suffix)

@ -7,7 +7,6 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
@ -25,7 +24,7 @@ namespace IoTNode.DeviceServices.Onvif
{
public class OnvifService : BaseDeviceService, IDisposable
{
private readonly ConcurrentDictionary<string, (Device camera, Process local, Process remote)> _list = new ConcurrentDictionary<string, (Device camera, Process local, Process remote)>();
private readonly ConcurrentDictionary<string, Process> _list = new ConcurrentDictionary<string, Process>();
private readonly IWebHostEnvironment _env;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IOnvifDeviceManagement _onvifDeviceManagement;
@ -145,12 +144,9 @@ namespace IoTNode.DeviceServices.Onvif
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));
this.UpdateData(deviceRepo, device, device.CreateData("mainrtmp", $"rtmp://{this._cfg["stream.rtmp"]}/live/main{ipCamera.Id}", DeviceDataType.String, "主码流rtmp"));
this.UpdateData(deviceRepo, device, device.CreateData("mainflv", $"http://{this._cfg["stream.flv"]}/live/main{ipCamera.Id}.flv", DeviceDataType.String, "主码流flv"));
this.UpdateData(deviceRepo, device, device.CreateData("mainhls", $"http://{this._cfg["stream.hls"]}/live/main{ipCamera.Id}.m3u8", DeviceDataType.String, "主码流hls"));
this.UpdateData(deviceRepo, device, device.CreateData("subrtmp", $"rtmp://{this._cfg["stream.rtmp"]}/live/sub{ipCamera.Id}", DeviceDataType.String, "子码流rtmp"));
this.UpdateData(deviceRepo, device, device.CreateData("subflv", $"http://{this._cfg["stream.flv"]}/live/sub{ipCamera.Id}.flv", DeviceDataType.String, "子码流flv"));
this.UpdateData(deviceRepo, device, device.CreateData("subhls", $"http://{this._cfg["stream.hls"]}/live/sub{ipCamera.Id}.m3u8", DeviceDataType.String, "子码流hls"));
this.UpdateData(deviceRepo, device, device.CreateData("rtmp", $"rtmp://{this._cfg["stream.rtmp"]}/live/{ipCamera.Id}", DeviceDataType.String, "rtmp"));
this.UpdateData(deviceRepo, device, device.CreateData("flv", $"http://{this._cfg["stream.flv"]}/live/{ipCamera.Id}.flv", DeviceDataType.String, "flv"));
this.UpdateData(deviceRepo, device, device.CreateData("hls", $"http://{this._cfg["stream.hls"]}/live/{ipCamera.Id}.m3u8", DeviceDataType.String, "hls"));
}
var profiles = this._onvifDeviceManagement.GetProfiles(ipCamera.DeviceUrl, ipCamera.MediaUrl);
var needAuth = false;
@ -183,26 +179,20 @@ namespace IoTNode.DeviceServices.Onvif
{
if (needAuth)
{
ipCamera.MainStreamUriXml = this._onvifDeviceManagement.GetStreamUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, device.UserName, device.Password, ipCamera.Profiles.First().Token);
ipCamera.MainSnapshotUriXml = this._onvifDeviceManagement.GetSnapshotUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, device.UserName, device.Password, ipCamera.Profiles.First().Token);
ipCamera.SubStreamUriXml = this._onvifDeviceManagement.GetStreamUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, device.UserName, device.Password, ipCamera.Profiles.Last().Token);
ipCamera.SubSnapshotUriXml = this._onvifDeviceManagement.GetSnapshotUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, device.UserName, device.Password, ipCamera.Profiles.Last().Token);
ipCamera.StreamUriXml = this._onvifDeviceManagement.GetStreamUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, device.UserName, device.Password, ipCamera.Profiles.First().Token);
ipCamera.SnapshotUriXml = this._onvifDeviceManagement.GetSnapshotUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, device.UserName, device.Password, ipCamera.Profiles.First().Token);
}
else
{
ipCamera.MainStreamUriXml = this._onvifDeviceManagement.GetStreamUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, ipCamera.Profiles.First().Token);
ipCamera.MainSnapshotUriXml = this._onvifDeviceManagement.GetSnapshotUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, ipCamera.Profiles.First().Token);
ipCamera.SubStreamUriXml = this._onvifDeviceManagement.GetStreamUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, ipCamera.Profiles.Last().Token);
ipCamera.SubSnapshotUriXml = this._onvifDeviceManagement.GetSnapshotUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, ipCamera.Profiles.Last().Token);
ipCamera.StreamUriXml = this._onvifDeviceManagement.GetStreamUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, ipCamera.Profiles.First().Token);
ipCamera.SnapshotUriXml = this._onvifDeviceManagement.GetSnapshotUri(ipCamera.DeviceUrl, ipCamera.MediaUrl, ipCamera.Profiles.First().Token);
}
ipCamera.ParseStreamUri();
ipCamera.ParseSnapshotUri();
this.UpdateData(deviceRepo, device, device.CreateData("MainToken", ipCamera.Profiles.First().Token, DeviceDataType.String, "主码流Token"));
this.UpdateData(deviceRepo, device, device.CreateData("SubToken", ipCamera.Profiles.Last().Token, DeviceDataType.String, "子码流Token"));
this.UpdateData(deviceRepo, device, device.CreateData("MainStreamUri", ipCamera.MainStreamUri, DeviceDataType.String, "主码流地址"));
this.UpdateData(deviceRepo, device, device.CreateData("MainSnapshotUri", ipCamera.MainSnapshotUri, DeviceDataType.String, "主码流截图地址"));
this.UpdateData(deviceRepo, device, device.CreateData("SubStreamUri", ipCamera.SubStreamUri, DeviceDataType.String, "子码流地址"));
this.UpdateData(deviceRepo, device, device.CreateData("SubSnapshotUri", ipCamera.SubSnapshotUri, DeviceDataType.String, "子码流截图地址"));
this.UpdateData(deviceRepo, device, device.CreateData("Token", ipCamera.Profiles.First().Token, DeviceDataType.String, "Token"));
this.UpdateData(deviceRepo, device, device.CreateData("StreamUri", ipCamera.StreamUri, DeviceDataType.String, "流地址"));
this.UpdateData(deviceRepo, device, device.CreateData("SnapshotUri", ipCamera.SnapshotUri, DeviceDataType.String, "截图地址"));
}
}
catch (Exception ex)
@ -214,13 +204,6 @@ namespace IoTNode.DeviceServices.Onvif
this.UpdateData(deviceRepo, device, device.CreateData("DeviceUrl", ipCamera.DeviceUrl, DeviceDataType.String, "设备地址"));
this.UpdateData(deviceRepo, device, device.CreateData("PtzAddress", ipCamera.PTZAddress, DeviceDataType.String, "云台地址"));
this.UpdateData(deviceRepo, device, device.CreateData("Ptz3DZoomSupport", ipCamera.Ptz3DZoomSupport ? "是" : "否", DeviceDataType.String, "缩放支持"));
//deviceRepo.SaveChanges();
//var deviceDto = device.To<EditDeviceModel>();
//this.SendToServer(Methods.EditDevice, deviceDto);
//foreach (var item in device.Data.Where(o => !o.Hidden))
//{
// this.SendDataToServer(item);
//}
}
}
catch (Exception ex)
@ -299,7 +282,7 @@ namespace IoTNode.DeviceServices.Onvif
{
var repo = scope.ServiceProvider.GetService<IRepository<Device>>();
var camera = repo.ReadOnlyTable().Include(o => o.Data).FirstOrDefault(o => o.Number == key);
if (camera != null && camera.Data.FirstOrDefault(o => o.Key == "Push").Value == "是")// && camera.Publish && (!camera.NeedAuth || (camera.NeedAuth && camera.HasAuth)))
if (camera != null && camera.Data.FirstOrDefault(o => o.Key == "Push").Value == "是")
{
if (camera.Data.FirstOrDefault(o => o.Key == "NeedAuth").Value == "否" || camera.Data.FirstOrDefault(o => o.Key == "HasAuth").Value == "是")
{
@ -317,50 +300,41 @@ namespace IoTNode.DeviceServices.Onvif
}
var needAuth = camera.Data.FirstOrDefault(o => o.Key == "NeedAuth").Value == "是";
var hasAuth = camera.Data.FirstOrDefault(o => o.Key == "HasAuth").Value == "是";
var mainStreamUri = camera.Data.FirstOrDefault(o => o.Key == "MainStreamUri").Value;
var mainRtspUrl = $"rtsp://{(needAuth ? $"{camera.UserName}:{camera.Password}@" : "")}{mainStreamUri.Substring(7)}";
var subStreamUri = camera.Data.FirstOrDefault(o => o.Key == "SubStreamUri").Value;
var subRtspUrl = $"rtsp://{(needAuth ? $"{camera.UserName}:{camera.Password}@" : "")}{subStreamUri.Substring(7)}";
var streamUri = camera.Data.FirstOrDefault(o => o.Key == "StreamUri").Value;
var rtspUrl = $"rtsp://{(needAuth ? $"{camera.UserName}:{camera.Password}@" : "")}{streamUri.Substring(7)}";
var fileName = $"ffmpeg-{Helper.Instance.GetRunTime()}{(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "")}";
var file = camera.GetData("ffmpeg.file")?.Value;
var mainRtmp = camera.Data.FirstOrDefault(o => o.Key == "mainrtmp").Value;
var subRtmp = camera.Data.FirstOrDefault(o => o.Key == "subrtmp").Value;
var rtmp = camera.Data.FirstOrDefault(o => o.Key == "rtmp").Value;
Console.WriteLine(file);
var arguments = camera.Data.FirstOrDefault(o => o.Key == "ffmpeg.args").Value;
Process main = null, sub = null;
if (!string.IsNullOrEmpty(mainStreamUri))
Process process = null;
if (!string.IsNullOrEmpty(streamUri))
{
if (!string.IsNullOrEmpty(mainRtmp))
{
main = this.SetProcess(file, string.Format(arguments, Environment.ProcessorCount, mainRtspUrl, mainRtmp));
}
if (!string.IsNullOrEmpty(subRtmp))
if (!string.IsNullOrEmpty(rtmp))
{
sub = this.SetProcess(file, string.Format(arguments, Environment.ProcessorCount, subRtspUrl, subRtmp));
process = this.SetProcess(file, string.Format(arguments, Environment.ProcessorCount, rtspUrl, rtmp));
}
}
if (this._list.TryAdd(camera.Number, (camera, main, sub)))
if (this._list.TryAdd(camera.Number, process))
{
Console.WriteLine($"add {camera.Number} to list");
}
else
{
if (main != null)
if (process != null)
{
this.CloseProcess(main);
this.CloseProcess(sub);
this.CloseProcess(process);
}
}
}
public void StopPushToServer(string key)
{
(Device camera, Process local, Process remote) item;
if (this._list.TryRemove(key, out item))
Process process;
if (this._list.TryRemove(key, out process))
{
Console.WriteLine($"OnvifService>remove {key} from list");
this.CloseProcess(item.local);
this.CloseProcess(item.remote);
this.CloseProcess(process);
}
}
@ -387,7 +361,7 @@ namespace IoTNode.DeviceServices.Onvif
Console.WriteLine($"ffmpeg processes list:{_list.Count},exit:{_process.ExitCode},args:{arguments}");
if (_process != null)
{
Thread.Sleep(100);
Thread.Sleep(3000);
_process.CancelErrorRead();
_process.Start();
_process.BeginErrorReadLine();
@ -422,20 +396,23 @@ namespace IoTNode.DeviceServices.Onvif
private void CloseProcess(Process process)
{
Console.WriteLine($"close process:{process?.StartInfo?.FileName} with {process?.StartInfo?.Arguments}");
try
{
if (process != null)
{
process.EnableRaisingEvents = false;
process.Kill();
//process.WaitForExit();
process.Dispose();
process?.Kill();
}
}
catch (Exception ex)
{
ex.PrintStack($"error when close ffmpeg process {ex.Message}");
}
finally
{
process?.Dispose();
}
}
private string GetOnoce(string deviceUrl)
@ -518,7 +495,7 @@ namespace IoTNode.DeviceServices.Onvif
if (!string.IsNullOrEmpty(ptzAddress))
{
var deviceUrl = camera.GetDataValue("DeviceUrl");
RequestXml(ptzAddress, MessageTemplate.StopAction, String.Format(MessageTemplate.StopMessage, camera.GetDataValue("MainToken"), true, true), camera.UserName, camera.Password, GetOnoce(deviceUrl));
RequestXml(ptzAddress, MessageTemplate.StopAction, String.Format(MessageTemplate.StopMessage, camera.GetDataValue("Token"), true, true), camera.UserName, camera.Password, GetOnoce(deviceUrl));
}
}
}
@ -532,31 +509,15 @@ namespace IoTNode.DeviceServices.Onvif
if (!string.IsNullOrEmpty(ptzAddress))
{
var deviceUrl = camera.GetDataValue("DeviceUrl");
RequestXml(ptzAddress, MessageTemplate.ContinuousMoveAction, String.Format(MessageTemplate.ContinuousMoveMessage, camera.GetDataValue("MainToken"), zx, px, py), camera.UserName, camera.Password, GetOnoce(deviceUrl));
RequestXml(ptzAddress, MessageTemplate.ContinuousMoveAction, String.Format(MessageTemplate.ContinuousMoveMessage, camera.GetDataValue("Token"), zx, px, py), camera.UserName, camera.Password, GetOnoce(deviceUrl));
}
}
}
public byte[] MainScreenShot(string id)
{
var camera = this.GetCamera(id);
var url = camera.GetDataValue("MainSubSnapshotUri");
if (string.IsNullOrEmpty(url))
{
return new byte[] { };
}
var hc = this._httpClientFactory.CreateClient();
if (camera.GetDataValue("NeedAuth") == "否")
{
return hc.GetByteArrayAsync(url).Result;
}
return hc.GetByteDigest(new Uri(url), camera.UserName, camera.Password);
}
public byte[] SubScreenShot(string id)
public byte[] ScreenShot(string id)
{
var camera = this.GetCamera(id);
var url = camera.GetDataValue("SubSnapshotUri");
var url = camera.GetDataValue("SnapshotUri");
if (string.IsNullOrEmpty(url))
{
return new byte[] { };
@ -607,7 +568,6 @@ namespace IoTNode.DeviceServices.Onvif
if (data != null)
{
data.Value = state ? "是" : "否";
//this.UpdateData(repo, device, data);
this.SendToServer(Methods.UpdateDvr, data);
}
}
@ -616,7 +576,7 @@ namespace IoTNode.DeviceServices.Onvif
private byte[] ScreenShot(Device camera)
{
var url = camera.GetDataValue("SubSnapshotUri");
var url = camera.GetDataValue("SnapshotUri");
if (string.IsNullOrEmpty(url))
{
return new byte[] { };

@ -34,12 +34,12 @@ namespace IoTNode
services.AddTransient<IEmailSender, EmptyEmailSender>();
services.AddTransient<IoTNodeJob>();
services.AddSingleton<IoTNodeClient>();
services.AddSingleton<OnvifService>();
services.AddSingleton<FBeeService>();
services.AddSingleton<SerialPortService>();
services.AddHostedService(o => o.GetService<IoTNodeClient>());
services.AddSingleton<OnvifService>();
services.AddHostedService(o => o.GetService<OnvifService>());
services.AddSingleton<FBeeService>();
services.AddHostedService(o => o.GetService<FBeeService>());
services.AddSingleton<SerialPortService>();
services.AddHostedService(o => o.GetService<SerialPortService>());
base.ConfigureServices(services);
}

Loading…
Cancel
Save