1
0
Fork 0

视频监控

develop
panliang 2023-05-05 15:12:15 +08:00
parent d1a14556f2
commit 180f2e070d
6 changed files with 145 additions and 69 deletions

View File

@ -2,17 +2,12 @@
namespace App\Admin\Controllers; namespace App\Admin\Controllers;
use Slowlyo\OwlAdmin\Renderers\Page; use Slowlyo\OwlAdmin\Renderers\{Button, Form, Page, TableColumn, TextControl, Component, CRUDTable, Card, Video, DateRangeControl};
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\TableColumn;
use Slowlyo\OwlAdmin\Renderers\TextControl;
use Slowlyo\OwlAdmin\Renderers\CRUDTable;
use Slowlyo\OwlAdmin\Controllers\AdminController; use Slowlyo\OwlAdmin\Controllers\AdminController;
use App\Services\Admin\DeviceService; use App\Services\Admin\DeviceService;
use App\Models\Device; use App\Models\Device;
use App\Models\Keyword; use App\Models\Keyword;
use App\Admin\Components; use App\Admin\Components;
use Slowlyo\OwlAdmin\Renderers\Button;
class DeviceController extends AdminController class DeviceController extends AdminController
{ {
@ -68,18 +63,12 @@ class DeviceController extends AdminController
\amisMake()->SelectControl()->name('powered_by')->label('厂家')->options(Keyword::getByParentKey('device-factory')->pluck('name', 'id')->toArray())->required(true), \amisMake()->SelectControl()->name('powered_by')->label('厂家')->options(Keyword::getByParentKey('device-factory')->pluck('name', 'id')->toArray())->required(true),
TextControl::make()->name('model_sn')->label('型号'), TextControl::make()->name('model_sn')->label('型号'),
\amisMake()->RadiosControl()->name('type')->label('类型')->options(Device::typeMap())->required(true), \amisMake()->RadiosControl()->name('type')->label('类型')->options(Device::typeMap())->required(true),
//监控设备-额外参数 // 监控设备-额外参数
\amisMake()->TextControl()->name('extends.ip')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label('设备IP'), // rtsp://admin:lcdx12345@172.16.40.2:554/Streaming/Channels/5201
\amisMake()->TextControl()->name('extends.username')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label('设备用户名'), TextControl::make()->name('extends.rtsp_url')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label(__('device.rtsp_url')),
\amisMake()->TextControl()->name('extends.password')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label('设备密码'), // rtsp://admin:lcdx12345@172.16.40.2:554/Streaming/tracks/5201
\amisMake()->GroupControl()->body([ TextControl::make()->name('extends.rtsp_history')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label(__('device.rtsp_history')),
\amisMake()->TextControl()->name('extends.live_port')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label('实时端口'),
\amisMake()->TextControl()->name('extends.live_channel')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label('实时通道'),
]),
\amisMake()->GroupControl()->body([
\amisMake()->TextControl()->name('extends.back_port')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label('回放端口'),
\amisMake()->TextControl()->name('extends.back_channel')->hiddenOn('data.type != '.Device::TYPE_MONITOR)->label('回放通道'),
]),
Components::make()->keywordsTagControl('group_tags', '分组', 'device-group'), Components::make()->keywordsTagControl('group_tags', '分组', 'device-group'),
Components::make()->sortControl('sort', __('admin.order')), Components::make()->sortControl('sort', __('admin.order')),
TextControl::make()->name('is_enable')->type('switch')->default(1)->label('显示'), TextControl::make()->name('is_enable')->type('switch')->default(1)->label('显示'),
@ -101,64 +90,60 @@ class DeviceController extends AdminController
/** /**
* 监控设备列表 * 监控设备列表
*/ */
public function monitorList(){ public function monitorList()
return CRUDTable::make()->mode('cards')->columnsCount(3) {
->data([ if ($this->actionOfGetData()) {
'items' => [ return $this->response()->success($this->service->list());
[ }
'id'=>1, return CRUDTable::make()
'src'=>'' ->mode('cards')
// ws://183.221.204.29:8100/rtsp?url=cnRzcDovL2FkbWluOjEyMzQ1Njc4OXhAMTE3LjE3NC4xODQuMTE4OjkwMDkvY2FtL3JlYWxtb25pdG9yP2NoYW5uZWw9MSZzdWJ0eXBlPTA= ->hideCheckToggler()
], ->columnsCount(3)
] ->perPage(6)
]) ->affixHeader(false)
->filter([ ->filterTogglable(true)
'title' => '搜索条件', ->set('primaryField', $this->service->primaryKey())
'body' => [ ->api(admin_url($this->queryPath . '?_action=getData&_type=' . Device::TYPE_MONITOR))
\amisMake()->TextControl()->name('name')->label('点位名称')->size('sm'), ->footerToolbar(['statistics', 'pagination'])
amis('submit')->label(__('admin.search'))->level('primary'), ->headerToolbar([])
] ->filter($this->baseFilter()->actions([])->body([
]) TextControl::make()->name('name')->label('点位名称')->size('md'),
Button::make()->label(__('admin.reset'))->actionType('clear-and-submit'),
Component::make()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->actions([]) ->actions([])
->itemClassName('col-sm-4') ->itemClassName('col-sm-4')
->card([ ->card(Card::make()->header(['title' => '$name'])->body(Video::make()->videoType('video/x-flv')->muted(true)->autoPlay(true)->src('${src}')));
'header' => [],
'body' => amisMake()->Video()
// ->isLive(true)->videoType('video/x-flv')->muted(true)->autoPlay(true)
->src('${src}')
]);
} }
/** /**
* 监控历史视频 * 监控历史视频
*/ */
public function monitorVideoList(){ public function monitorVideoList()
return CRUDTable::make()->mode('cards')->columnsCount(3) {
->data([ if ($this->actionOfGetData()) {
'items' => [ return $this->response()->success($this->service->list());
[ }
'id'=>1, return CRUDTable::make()
'src'=>'' ->mode('cards')
// ws://183.221.204.29:8100/rtsp?url=cnRzcDovL2FkbWluOjEyMzQ1Njc4OXhAMTE3LjE3NC4xODQuMTE4OjkwMDkvY2FtL3JlYWxtb25pdG9yP2NoYW5uZWw9MSZzdWJ0eXBlPTA= ->hideCheckToggler()
], ->columnsCount(3)
] ->perPage(6)
]) ->affixHeader(false)
->filter([ ->filterTogglable(true)
'title' => '搜索条件', ->set('primaryField', $this->service->primaryKey())
'body' => [ ->api(admin_url($this->queryPath . '?_action=getData&_type=' . Device::TYPE_MONITOR . '&_mode=history'))
\amisMake()->TextControl()->name('name')->label('点位名称')->size('sm'), ->footerToolbar(['statistics', 'pagination'])
\amisMake()->DateRangeControl()->label('时间范围'), ->headerToolbar([])
amis('submit')->label(__('admin.search'))->level('primary'), ->filter($this->baseFilter()->actions([])->body([
] TextControl::make()->name('name')->label('点位名称')->size('md'),
]) DateRangeControl::make()->name('date')->label('日期')->maxDate('now')->size('md'),
Button::make()->label(__('admin.reset'))->actionType('clear-and-submit'),
Component::make()->setType('submit')->label(__('admin.search'))->level('primary'),
]))
->actions([]) ->actions([])
->itemClassName('col-sm-4') ->itemClassName('col-sm-4')
->card([ ->card(Card::make()->header(['title' => '$name'])->body(Video::make()->videoType('video/x-flv')->muted(true)->autoPlay(true)->src('${src}')));
'header' => [],
'body' => amisMake()->Video()
// ->isLive(true)->videoType('video/x-flv')->muted(true)->autoPlay(true)
->src('${src}')
]);
} }
/** /**

View File

@ -2,14 +2,12 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use EloquentFilter\Filterable; use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
class Device extends Model class Device extends Model
{ {
use HasFactory;
use Filterable; use Filterable;
public const TYPE_MONITOR = 1; //监控设备 public const TYPE_MONITOR = 1; //监控设备
@ -30,6 +28,10 @@ class Device extends Model
'group_tags' 'group_tags'
]; ];
protected $casts = [
'extends' => 'json'
];
protected function serializeDate(\DateTimeInterface $date){ protected function serializeDate(\DateTimeInterface $date){
return $date->format('Y-m-d H:i:s'); return $date->format('Y-m-d H:i:s');
} }

View File

@ -16,4 +16,33 @@ class DeviceService extends BaseService
protected array $withRelationships = ['factory']; protected array $withRelationships = ['factory'];
protected string $modelFilterName = DeviceFilter::class; protected string $modelFilterName = DeviceFilter::class;
public function list()
{
$query = $this->listQuery();
$items = (clone $query)->paginate(request()->input('perPage', 20))->items();
$base = settings()->get('rtsp_url');
if (request('_type') == Device::TYPE_MONITOR) {
$history = request('_mode') === 'history';
$date = explode(',', request('date'));
$start = data_get($date, 0);
$end = data_get($date, 1);
foreach ($items as &$item) {
$url = data_get($item->extends, $history ? 'rtsp_history' : 'rtsp_url');
$src = null;
if ($base && $url) {
// 查看历史监控
if ($history && $start && $end) {
$url .= '?start=' . date('Y-m-d', $start) . '&end=' . data('Y-m-d', $end);
}
$src = $base . base64_encode($url);
}
$item->src = $src;
}
}
$total = (clone $query)->count();
return compact('items', 'total');
}
} }

View File

@ -0,0 +1,26 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\Device;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Device>
*/
class DeviceFactory extends Factory
{
protected $model = Device::class;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'name' => $this->faker->name,
'sn' => $this->faker->isbn10(),
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Device;
use Database\Factories\DeviceFactory;
class DeviceSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Device::truncate();
(new DeviceFactory)->count(100)->create([
'type' => Device::TYPE_MONITOR,
// 'extends' => [
// 'rtsp_url' => 'rtsp://admin:lcdx12345@172.16.40.2:554/Streaming/Channels/5201',
// 'rtsp_history' => 'rtsp://admin:lcdx12345@172.16.40.2:554/Streaming/tracks/5201',
// ]
]);
}
}

View File

@ -0,0 +1,6 @@
<?php
return [
'rtsp_url' => 'RTSP 直播流',
'rtsp_history' => 'RTSP 回放流',
];