Commit 4a171c48 by liulongfei

1. 添加算法错误标记按钮

2. 修复仅显示本地NDI流按钮失效的bug
parent 85f2863b
......@@ -55,5 +55,10 @@ namespace VIZ.H2V.Connection
/// 1. 单人机位 Single
/// </remarks>
public const string manual_correction = "manual_correction";
/// <summary>
/// 错误标记
/// </summary>
public const string wrong_target = "wrong_target";
}
}
......@@ -90,6 +90,8 @@ namespace VIZ.H2V.Connection
{
package.id = option.id;
package.enable_sendto_crop = option.enable_sendto_crop ? 1 : 0;
package.target_bbox = option.target_bbox;
package.timecode = option.timecode;
manager.SendJson(package);
}
......
......@@ -26,5 +26,15 @@ namespace VIZ.H2V.Connection
/// 手动校准(x,y,r)
/// </summary>
public List<int> correction_area { get; set; }
/// <summary>
/// 错误目标框(left,top,right,bottom)
/// </summary>
public List<int> target_bbox { get; set; }
/// <summary>
/// 时间码
/// </summary>
public long timecode { get; set; }
}
}
......@@ -47,5 +47,15 @@ namespace VIZ.H2V.Connection
/// 是否启用边线检测
/// </summary>
public int border_on { get; set; }
/// <summary>
/// 错误目标框
/// </summary>
public List<int> target_bbox { get; set; }
/// <summary>
/// 时间码
/// </summary>
public long timecode { get; set; }
}
}
......@@ -127,7 +127,7 @@
<Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="BorderBrush" Value="White"></Setter>
<Setter Property="BorderThickness" Value="2"></Setter>
<Setter Property="BorderThickness" Value="4"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
......
......@@ -164,11 +164,11 @@ namespace VIZ.H2V.Module
#endregion
#region IsShowLocalStream -- 是否显示本地流
#region IsShowLocalStream -- 是否仅显示本机输入源
private bool isShowLocalStream = true;
/// <summary>
/// 是否显示本地流
/// 是否仅显示本机输入源
/// </summary>
public bool IsShowLocalStream
{
......@@ -177,7 +177,7 @@ namespace VIZ.H2V.Module
{
isShowLocalStream = value;
this.RaisePropertyChanged(nameof(IsShowLocalStream));
this.RaisePropertyChanged(nameof(NDIStreamInfosView));
this.NDIStreamInfosView.Refresh();
}
}
......
......@@ -201,6 +201,13 @@ namespace VIZ.H2V.Module
public abstract void BorderPoint(AlgorithmInfo_borderpoint boarderpoint);
/// <summary>
/// 错误标记
/// </summary>
/// <param name="target_bbox">目标框</param>
/// <param name="timeCode">时间码</param>
public abstract void ErrorTag(List<int> target_bbox, long timeCode);
/// <summary>
/// 手动校准
/// </summary>
/// <param name="info">手动校准信息</param>
......
......@@ -71,6 +71,13 @@ namespace VIZ.H2V.Module
void ManualCorrection(ManualCorrectionInfo info);
/// <summary>
/// 错误标记
/// </summary>
/// <param name="target_bbox">目标框</param>
/// <param name="timeCode">时间码</param>
void ErrorTag(List<int> target_bbox, long timeCode);
/// <summary>
/// 初始化算法
/// </summary>
/// <remarks>
......
......@@ -111,6 +111,27 @@ namespace VIZ.H2V.Module
}
/// <summary>
/// 错误标记
/// </summary>
/// <param name="target_bbox">目标框</param>
/// <param name="timeCode">时间码</param>
public override void ErrorTag(List<int> target_bbox, long timeCode)
{
if (target_bbox == null || target_bbox.Count != 4 || timeCode <= 0)
return;
UdpEndpointManager manager = ConnectionManager.UdpConnection.GetEndpointManager(this.Support.ViewKey);
AlgorithmSenderOption option = new AlgorithmSenderOption();
option.id = this.Support.ID;
option.enable_sendto_crop = this.Support.ViewConfig.IsSendToCrop;
option.target_bbox = target_bbox;
option.timecode = timeCode;
AlgorithmSender.AutoMode(manager, this.BuildPackage(AlgorithmAutoModeCmd.wrong_target, null), option);
}
/// <summary>
/// 手动校准
/// </summary>
/// <param name="info">手动校准信息</param>
......
......@@ -121,6 +121,27 @@ namespace VIZ.H2V.Module
}
/// <summary>
/// 错误标记
/// </summary>
/// <param name="target_bbox">目标框</param>
/// <param name="timeCode">时间码</param>
public override void ErrorTag(List<int> target_bbox, long timeCode)
{
if (target_bbox == null || target_bbox.Count != 4 || timeCode <= 0)
return;
UdpEndpointManager manager = ConnectionManager.UdpConnection.GetEndpointManager(this.Support.ViewKey);
AlgorithmSenderOption option = new AlgorithmSenderOption();
option.id = this.Support.ID;
option.enable_sendto_crop = this.Support.ViewConfig.IsSendToCrop;
option.target_bbox = target_bbox;
option.timecode = timeCode;
AlgorithmSender.AutoMode(manager, this.BuildPackage(AlgorithmAutoModeCmd.wrong_target, null, null), option);
}
/// <summary>
/// 手动校准
/// </summary>
/// <param name="info">手动校准信息</param>
......
......@@ -158,6 +158,27 @@ namespace VIZ.H2V.Module
}
/// <summary>
/// 错误标记
/// </summary>
/// <param name="target_bbox">目标框</param>
/// <param name="timeCode">时间码</param>
public override void ErrorTag(List<int> target_bbox, long timeCode)
{
if (target_bbox == null || target_bbox.Count != 4 || timeCode <= 0)
return;
UdpEndpointManager manager = ConnectionManager.UdpConnection.GetEndpointManager(this.Support.ViewKey);
AlgorithmSenderOption option = new AlgorithmSenderOption();
option.id = this.Support.ID;
option.enable_sendto_crop = this.Support.ViewConfig.IsSendToCrop;
option.target_bbox = target_bbox;
option.timecode = timeCode;
AlgorithmSender.AutoMode(manager, this.BuildPackage(AlgorithmAutoModeCmd.wrong_target, null), option);
}
/// <summary>
/// 手动校准
/// </summary>
/// <param name="info">手动校准信息</param>
......
......@@ -121,6 +121,27 @@ namespace VIZ.H2V.Module
}
/// <summary>
/// 错误标记
/// </summary>
/// <param name="target_bbox">目标框</param>
/// <param name="timeCode">时间码</param>
public override void ErrorTag(List<int> target_bbox, long timeCode)
{
if (target_bbox == null || target_bbox.Count != 4 || timeCode <= 0)
return;
UdpEndpointManager manager = ConnectionManager.UdpConnection.GetEndpointManager(this.Support.ViewKey);
AlgorithmSenderOption option = new AlgorithmSenderOption();
option.id = this.Support.ID;
option.enable_sendto_crop = this.Support.ViewConfig.IsSendToCrop;
option.target_bbox = target_bbox;
option.timecode = timeCode;
AlgorithmSender.AutoMode(manager, this.BuildPackage(AlgorithmAutoModeCmd.wrong_target, null, null), option);
}
/// <summary>
/// 手动校准
/// </summary>
/// <param name="info">手动校准信息</param>
......
......@@ -121,6 +121,27 @@ namespace VIZ.H2V.Module
}
/// <summary>
/// 错误标记
/// </summary>
/// <param name="target_bbox">目标框</param>
/// <param name="timeCode">时间码</param>
public override void ErrorTag(List<int> target_bbox, long timeCode)
{
if (target_bbox == null || target_bbox.Count != 4 || timeCode <= 0)
return;
UdpEndpointManager manager = ConnectionManager.UdpConnection.GetEndpointManager(this.Support.ViewKey);
AlgorithmSenderOption option = new AlgorithmSenderOption();
option.id = this.Support.ID;
option.enable_sendto_crop = this.Support.ViewConfig.IsSendToCrop;
option.target_bbox = target_bbox;
option.timecode = timeCode;
AlgorithmSender.AutoMode(manager, this.BuildPackage(AlgorithmAutoModeCmd.wrong_target, null, null), option);
}
/// <summary>
/// 手动校准
/// </summary>
/// <param name="info">手动校准信息</param>
......
......@@ -299,7 +299,16 @@
<!-- AI功能区 -->
<StackPanel Orientation="Vertical" VerticalAlignment="Bottom" Grid.Row="1">
<Rectangle Height="2" Width="30" Fill="#AAFFFFFF" Margin="0,2,0,0"></Rectangle>
<!-- 错误标记 -->
<!--<Border Margin="0,10,0,8">
<Button Width="32" Height="32"
Style="{StaticResource Button_Function}"
IsEnabled="{Binding Path=ViewStatus,Converter={StaticResource NDIViewStatus2IsEnabledConverter_SettingButton}}"
Command="{Binding AlgorithmErrorTagCommand}">
<Image Width="24" Height="24" Source="/VIZ.H2V.Module.Resource;component/Icons/ai_close_24x24.png"></Image>
</Button>
</Border>-->
<!-- 重启算法 -->
<Border Margin="0,10,0,0" ToolTip="重启算法" Background="Transparent">
<Button Width="32" Height="32"
Style="{StaticResource Button_Function}"
......@@ -308,6 +317,7 @@
<Image Width="24" Height="24" Source="/VIZ.H2V.Module.Resource;component/Icons/ai_refresh_24x24.png"></Image>
</Button>
</Border>
<!-- 关闭算法 -->
<Border Margin="0,10,0,0" ToolTip="关闭算法" Background="Transparent">
<Button Width="32" Height="32"
Style="{StaticResource Button_Function}"
......
......@@ -487,5 +487,55 @@ namespace VIZ.H2V.Module
}
#endregion
#region AlgorithmErrorTagCommand -- 算法错误标记命令
/// <summary>
/// 算法错误标记命令
/// </summary>
public VCommand AlgorithmErrorTagCommand { get; set; }
/// <summary>
/// 算法错误标记
/// </summary>
private void AlgorithmErrorTag()
{
// 只有在自动模式下可以标记
if (this.StrategyMode != AlgorithmStrategyMode.auto_mode)
return;
// 只有裁切状态下可以标记
if (this.ViewStatus != NDIViewStatus.CropRoi)
return;
NDIView view = this.GetView<NDIView>();
if (view == null)
return;
VideoRenderInfo renderInfo = view.video.GetRenderInfo();
if (renderInfo == null)
return;
TrackingBoxPlugin trackingBoxPlugin = view.video.GetPlugin<TrackingBoxPlugin>(VideoControlPluginNames.TrackingBox);
if (trackingBoxPlugin == null)
return;
List<TrackingBoxInfo> trackingBoxInfos = trackingBoxPlugin.GetTrackingBoxInfos();
if (trackingBoxInfos == null || trackingBoxInfos.Count == 0)
return;
TrackingBoxInfo boxInfo = trackingBoxInfos[0];
// 标记错误
List<int> box = new List<int>();
box.Add((int)boxInfo.SrcRect.Left);
box.Add((int)boxInfo.SrcRect.Top);
box.Add((int)boxInfo.SrcRect.Right);
box.Add((int)boxInfo.SrcRect.Bottom);
this.AlgorithmControllerDic[this.StrategyType].ErrorTag(box, renderInfo.Frame.TimeStamp);
}
#endregion
}
}
......@@ -80,6 +80,7 @@ namespace VIZ.H2V.Module
this.IsAreaCorrectionEnabledChangedCommand = new VCommand(this.IsAreaCorrectionEnabledChanged);
this.SaveAlgorithmConfigCommand = new VCommand(this.SaveAlgorithmConfig);
this.SetActiveCommand = new VCommand(this.SetActive);
this.AlgorithmErrorTagCommand = new VCommand(this.AlgorithmErrorTag);
}
/// <summary>
......
......@@ -192,26 +192,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="VideoMainView\View\VideoMainView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Generic.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="VideoView\View\VideoSettingView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="VideoView\View\VideoControlView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="VideoView\View\VideoView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="NDIMainView\Controller\Gpio\GpioController.cs" />
......@@ -315,10 +299,6 @@
<Compile Include="SystemSetting\View\TallySettingPanelView.xaml.cs">
<DependentUpon>TallySettingPanelView.xaml</DependentUpon>
</Compile>
<Compile Include="VideoMainView\View\VideoMainView.xaml.cs">
<DependentUpon>VideoMainView.xaml</DependentUpon>
</Compile>
<Compile Include="VideoMainView\ViewModel\VideoMainViewModel.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
......@@ -333,20 +313,6 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Setup\Provider\AppSetup_InitLiteDb.cs" />
<Compile Include="VideoView\Service\IVideoControlService.cs" />
<Compile Include="VideoView\ViewModel\VideoSettingViewModel.cs" />
<Compile Include="VideoView\View\VideoSettingView.xaml.cs">
<DependentUpon>VideoSettingView.xaml</DependentUpon>
</Compile>
<Compile Include="VideoView\View\VideoControlView.xaml.cs">
<DependentUpon>VideoControlView.xaml</DependentUpon>
</Compile>
<Compile Include="VideoView\Service\IVideoService.cs" />
<Compile Include="VideoView\ViewModel\VideoControlViewModel.cs" />
<Compile Include="VideoView\View\VideoView.xaml.cs">
<DependentUpon>VideoView.xaml</DependentUpon>
</Compile>
<Compile Include="VideoView\ViewModel\VideoViewModel.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
......
<UserControl x:Class="VIZ.H2V.Module.VideoMainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:VIZ.H2V.Module"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/VIZ.Framework.Common.Resource;component/Style/Button/Button_WindowTop.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<!-- 头部 -->
<TextBlock Text="AI横转竖智能剪切系统" FontSize="20" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
<StackPanel Orientation="Horizontal" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Top">
<Button Command="{Binding Path=MinCommand}" Style="{StaticResource Button_Min}"></Button>
<Button Command="{Binding Path=CloseCommand}" Style="{StaticResource Button_Close}"></Button>
</StackPanel>
<!-- 视频区域 -->
<Grid Grid.Row="1" Margin="20,0,20,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<local:VideoView Key="CAM1" Grid.Row="0" Grid.Column="0"></local:VideoView>
<local:VideoView Key="CAM2" Grid.Row="0" Grid.Column="1"></local:VideoView>
<local:VideoView Key="CAM3" Grid.Row="1" Grid.Column="0"></local:VideoView>
<local:VideoView Key="CAM4" Grid.Row="1" Grid.Column="1"></local:VideoView>
</Grid>
<!-- 状态区域 -->
<local:VideoControlView Grid.Row="2"></local:VideoControlView>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VIZ.Framework.Core;
namespace VIZ.H2V.Module
{
/// <summary>
/// VideoMainView.xaml 的交互逻辑
/// </summary>
public partial class VideoMainView : UserControl
{
public VideoMainView()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new VideoMainViewModel());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
using VIZ.Framework.Common;
using System.Windows;
namespace VIZ.H2V.Module
{
/// <summary>
/// 主视图模型
/// </summary>
public class VideoMainViewModel : ViewModelBase
{
/// <summary>
/// 视频视图模型
/// </summary>
public VideoMainViewModel()
{
// 初始化命令
this.InitCommand();
// 初始化消息
this.InitMessage();
// 初始化属性
this.InitProperty();
}
/// <summary>
/// 初始化命令
/// </summary>
private void InitCommand()
{
this.LoadedCommand = new VCommand(this.Loaded);
this.MinCommand = new VCommand(this.Min);
this.CloseCommand = new VCommand(this.Close);
}
/// <summary>
/// 初始化消息
/// </summary>
private void InitMessage()
{
}
/// <summary>
/// 初始化属性
/// </summary>
private void InitProperty()
{
}
// ======================================================================================
// === Property ===
// ======================================================================================
// ======================================================================================
// === Command ===
// ======================================================================================
#region LoadedCommand -- 加载命令
/// <summary>
/// 加载命令
/// </summary>
public VCommand LoadedCommand { get; set; }
/// <summary>
///
/// </summary>
private void Loaded()
{
}
#endregion
#region CloseCommand -- 关闭命令
/// <summary>
/// 关闭命令
/// </summary>
public VCommand CloseCommand { get; set; }
/// <summary>
/// 关闭
/// </summary>
private void Close()
{
VideoMainView view = this.GetView<VideoMainView>();
if (view == null)
return;
MessageBoxExResult result = MessageBoxEx.ShowDialog("提示", "确定退出?", MessageBoxExButtons.YES_CANCEL);
if (result != MessageBoxExResult.YES)
return;
Window window = WPFHelper.GetAncestorByType<Window>(view);
if (window == null)
return;
window.Close();
}
#endregion
#region MinCommand -- 最小化窗口命令
/// <summary>
/// 最小化窗口命令
/// </summary>
public VCommand MinCommand { get; set; }
/// <summary>
/// 最小化
/// </summary>
private void Min()
{
VideoMainView view = this.GetView<VideoMainView>();
if (view == null)
return;
Window window = WPFHelper.GetAncestorByType<Window>(view);
if (window == null)
return;
window.WindowState = WindowState.Minimized;
}
#endregion
// ======================================================================================
// === Message ===
// ======================================================================================
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
namespace VIZ.H2V.Module
{
/// <summary>
/// 視頻控制服务
/// </summary>
public interface IVideoControlService : IService
{
/// <summary>
/// 播放是否可用
/// </summary>
bool IsPlayEnabled { get; set; }
/// <summary>
/// 暂停是否可用
/// </summary>
bool IsPauseEnabled { get; set; }
/// <summary>
/// 停止是否可用
/// </summary>
bool IsStopEnabled { get; set; }
/// <summary>
/// 时间滑块是否可用
/// </summary>
bool IsTimeBarEnabled { get; set; }
/// <summary>
/// 更新时间条信息
/// </summary>
void UpdateTimeBarInfo();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Common;
using VIZ.Framework.Core;
using VIZ.H2V.Domain;
namespace VIZ.H2V.Module
{
/// <summary>
/// 视频服务
/// </summary>
public interface IVideoService : IService
{
/// <summary>
/// OpenCV键
/// </summary>
string OpenCVKey { get; set; }
/// <summary>
/// 视频模型
/// </summary>
VideoModel VideoModel { get; set; }
/// <summary>
/// 打开文件
/// </summary>
/// <param name="fileName">文件名</param>
void Open(string fileName);
/// <summary>
/// 播放
/// </summary>
void Play();
/// <summary>
/// 暂停
/// </summary>
void Pause();
/// <summary>
/// 停止
/// </summary>
void Stop();
/// <summary>
/// 设置位置
/// </summary>
/// <param name="position">帧位置</param>
void SetPosition(int position);
/// <summary>
/// 获取OpenCV属性信息
/// </summary>
/// <returns>OpenCV属性信息</returns>
OpenCVPropertyInfos GetOpenCVPropertyInfos();
}
}
<UserControl x:Class="VIZ.H2V.Module.VideoControlView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fcommon="clr-namespace:VIZ.Framework.Common;assembly=VIZ.Framework.Common"
xmlns:local="clr-namespace:VIZ.H2V.Module"
xmlns:fcore="clr-namespace:VIZ.Framework.Core;assembly=VIZ.Framework.Core"
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
d:DataContext="{d:DesignInstance Type=local:VideoControlViewModel}"
mc:Ignorable="d"
d:DesignHeight="60" d:DesignWidth="1920">
<UserControl.Resources>
<ResourceDictionary>
<fcore:TimeSpan2DoubleConverter x:Key="TimeSpan2DoubleConverter" Type="Second"></fcore:TimeSpan2DoubleConverter>
<fcore:Double2TimeSpanConverter x:Key="Double2TimeSpanConverter" Type="Second"></fcore:Double2TimeSpanConverter>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140"></ColumnDefinition>
<ColumnDefinition Width="140"></ColumnDefinition>
<ColumnDefinition Width="140"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="140"></ColumnDefinition>
<ColumnDefinition Width="140"></ColumnDefinition>
<ColumnDefinition Width="350"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- 播放器控制 -->
<Button Content="播放" Width="120" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0"
Command="{Binding Path=PlayCommand}"
IsEnabled="{Binding Path=IsPlayEnabled}"></Button>
<Button Content="暂停" Width="120" Height="40" Margin="10,0,10,0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1"
Command="{Binding Path=PauseCommand}"
IsEnabled="{Binding Path=IsPauseEnabled}"></Button>
<Button Content="停止" Width="120" Height="40" Margin="10,0,10,0" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="2"
Command="{Binding Path=StopCommmand}"
IsEnabled="{Binding Path=IsStopEnabled}"></Button>
<fcommon:VideoTimeBar Grid.Column="3" Foreground="White" FontSize="14"
Time="{Binding Path=PositionTime,Mode=OneWay}"
MaxTime="{Binding TotalTime,Mode=TwoWay}"
IsEnabled="{Binding Path=IsTimeBarEnabled}" >
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="TimeBarManualValueChanged">
<behaviors:InvokeCommandAction Command="{Binding TimeBarManualValueChangedCommand}" PassEventArgsToCommand="True" />
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
</fcommon:VideoTimeBar>
<Button Content="倒退5秒" Width="120" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="4"
Command="{Binding Path=BackCommand}"
IsEnabled="{Binding Path=IsStopEnabled}"></Button>
<Button Content="前进5秒" Width="120" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="5"
Command="{Binding Path=ForwardCommand}"
IsEnabled="{Binding Path=IsStopEnabled}"></Button>
<Grid Grid.Column="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="跳转至:" FontSize="16" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBox Grid.Column="1" Padding="10,0,10,0" VerticalAlignment="Center"
Height="40" VerticalContentAlignment="Center" AcceptsReturn="False"
Text="{Binding Path=GotoString,Mode=TwoWay}"
ToolTip="时间格式:00:00:00"></TextBox>
<Button Grid.Column="2" Content="跳转" Width="120" Height="40"
Command="{Binding Path=GotoCommand}"
IsEnabled="{Binding Path=IsStopEnabled}"></Button>
</Grid>
<!-- 视频设置 -->
<Button Width="120" Height="40" HorizontalAlignment="Right" Margin="10,0,10,0" Content="视频设置" Grid.Column="7"
Command="{Binding Path=SettingCommand}"></Button>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VIZ.Framework.Core;
namespace VIZ.H2V.Module
{
/// <summary>
/// VideoControlView.xaml 的交互逻辑
/// </summary>
public partial class VideoControlView : UserControl
{
public VideoControlView()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new VideoControlViewModel());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VIZ.Framework.Core;
namespace VIZ.H2V.Module
{
/// <summary>
/// VideoSettingView.xaml 的交互逻辑
/// </summary>
public partial class VideoSettingView : UserControl
{
public VideoSettingView()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new VideoSettingViewModel());
}
}
}
<UserControl x:Class="VIZ.H2V.Module.VideoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:VIZ.H2V.Module"
xmlns:fmodule="clr-namespace:VIZ.Framework.Common;assembly=VIZ.Framework.Common"
xmlns:fcore="clr-namespace:VIZ.Framework.Core;assembly=VIZ.Framework.Core"
d:DataContext="{d:DesignInstance Type=local:VideoViewModel}"
mc:Ignorable="d" x:Name="uc"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<fcore:Bool2VisibilityConverter x:Key="Bool2VisibilityConverter" TrueVisibility="Visible" FalseVisibility="Hidden"></fcore:Bool2VisibilityConverter>
</ResourceDictionary>
</UserControl.Resources>
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="Loaded">
<behaviors:InvokeCommandAction Command="{Binding LoadedCommand}" />
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="60"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- 标题 -->
<TextBlock Text="{Binding ElementName=uc,Path=Key,Mode=OneWay}"
HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Foreground="White"></TextBlock>
<!-- 视频区域 -->
<Border Grid.Row="1" BorderBrush="#ff4c4c4c" BorderThickness="1">
<fmodule:VideoControl x:Name="video" Visibility="{Binding Path=IsVideoShow,Converter={StaticResource Bool2VisibilityConverter}}"></fmodule:VideoControl>
</Border>
<!-- 其他 -->
<Grid Grid.Row="1" Grid.Column="1">
<CheckBox Content="显隐" Foreground="White" FontSize="16"
IsChecked="{Binding Path=IsVideoShow,Mode=TwoWay}"></CheckBox>
</Grid>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VIZ.Framework.Core;
using VIZ.Framework.Storage;
using VIZ.H2V.Domain;
namespace VIZ.H2V.Module
{
/// <summary>
/// VideoView.xaml 的交互逻辑
/// </summary>
public partial class VideoView : UserControl
{
public VideoView()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new VideoViewModel());
this.video.IsShowFPS = ApplicationDomainEx.IniStorage.GetValue<VideoConfig, bool>(p => p.VIDEO_IS_SHOW_FPS);
}
#region Key --
/// <summary>
/// 键
/// </summary>
public string Key
{
get { return (string)GetValue(KeyProperty); }
set { SetValue(KeyProperty, value); }
}
/// <summary>
/// Using a DependencyProperty as the backing store for Key. This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty KeyProperty =
DependencyProperty.Register("Key", typeof(string), typeof(VideoView), new PropertyMetadata(null));
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Common;
using VIZ.Framework.Core;
using VIZ.Framework.Domain;
using VIZ.H2V.Domain;
namespace VIZ.H2V.Module
{
/// <summary>
/// 视频视图模型
/// </summary>
public class VideoViewModel : ViewModelBase, IVideoService
{
/// <summary>
/// 视频视图模型
/// </summary>
public VideoViewModel()
{
// 初始化命令
this.InitCommand();
}
/// <summary>
/// 初始化命令
/// </summary>
private void InitCommand()
{
this.LoadedCommand = new VCommand(this.Loaded);
}
// ======================================================================================
// === Property ===
// ======================================================================================
#region OpenCVKey -- 视频键
private string openCVKey;
/// <summary>
/// 视频键
/// </summary>
public string OpenCVKey
{
get { return openCVKey; }
set { openCVKey = value; this.RaisePropertyChanged(nameof(OpenCVKey)); }
}
#endregion
#region IsVideoShow -- 是否显示视频
private bool isVideoShow = true;
/// <summary>
/// 是否显示视频
/// </summary>
public bool IsVideoShow
{
get { return isVideoShow; }
set { isVideoShow = value; this.RaisePropertyChanged(nameof(IsVideoShow)); }
}
#endregion
#region VideoModel -- 视频模型
private VideoModel videoModel;
/// <summary>
/// 视频模型
/// </summary>
public VideoModel VideoModel
{
get { return videoModel; }
set { videoModel = value; this.RaisePropertyChanged(nameof(VideoModel)); }
}
#endregion
// ======================================================================================
// === Command ===
// ======================================================================================
#region LoadedCommand -- 加载命令
/// <summary>
/// 加载命令
/// </summary>
public VCommand LoadedCommand { get; set; }
/// <summary>
/// 加载
/// </summary>
private void Loaded()
{
if (!string.IsNullOrWhiteSpace(this.OpenCVKey))
return;
VideoView view = this.GetView<VideoView>();
if (view == null)
return;
this.OpenCVKey = view.Key;
// 注册服务
ApplicationDomain.ServiceManager.AddService(this.OpenCVKey, this);
// 添加视频流工具
OpenCVStreamOption option = new OpenCVStreamOption();
OpenCVStream stream = new OpenCVStream(option);
stream.ExecuteVideoFrame += Stream_ExecuteVideoFrame;
VideoStreamManager.Append(this.OpenCVKey, stream);
}
/// <summary>
/// 处理视频
/// </summary>
private void Stream_ExecuteVideoFrame(object sender, VideoFrameEventArgs e)
{
if (!this.IsVideoShow)
{
e.Frame.Dispose();
return;
}
VideoView view = this.GetView<VideoView>();
if (view == null)
{
e.Frame.Dispose();
return;
}
view.video.UpdateVideoFrame(e.Frame);
}
#endregion
// ======================================================================================
// === Private Field ===
// ======================================================================================
// ======================================================================================
// === IVideoViewModelService ===
// ======================================================================================
/// <summary>
/// 打开文件
/// </summary>
/// <param name="fileName">文件名</param>
public void Open(string fileName)
{
OpenCVStream stream = VideoStreamManager.Get<OpenCVStream>(this.OpenCVKey);
if (stream == null)
return;
stream.ChangeUri(fileName);
this.SetPosition(0);
}
/// <summary>
/// 播放
/// </summary>
public void Play()
{
OpenCVStream stream = VideoStreamManager.Get<OpenCVStream>(this.OpenCVKey);
if (stream == null)
return;
stream.Play();
}
/// <summary>
/// 暂停
/// </summary>
public void Pause()
{
OpenCVStream stream = VideoStreamManager.Get<OpenCVStream>(this.OpenCVKey);
if (stream == null)
return;
stream.Pause();
}
/// <summary>
/// 停止
/// </summary>
public void Stop()
{
OpenCVStream stream = VideoStreamManager.Get<OpenCVStream>(this.OpenCVKey);
if (stream == null)
return;
stream.Stop();
this.SetPosition(0);
}
/// <summary>
/// 设置位置
/// </summary>
/// <param name="position">帧位置</param>
public void SetPosition(int position)
{
OpenCVStream stream = VideoStreamManager.Get<OpenCVStream>(this.OpenCVKey);
if (stream == null)
return;
if (this.VideoModel.OffsetSec != 0d)
{
OpenCVPropertyInfos propertyInfos = this.GetOpenCVPropertyInfos();
if (propertyInfos != null)
{
int offset = (int)(this.VideoModel.OffsetSec * propertyInfos.Fps);
position += offset;
position = position < 0 ? 0 : position;
}
}
stream.SetPosition(position);
stream.TriggerExecuteCurrentPosVideoFrame();
}
/// <summary>
/// 获取OpenCV属性信息
/// </summary>
/// <returns>OpenCV属性信息</returns>
public OpenCVPropertyInfos GetOpenCVPropertyInfos()
{
OpenCVStream stream = VideoStreamManager.Get<OpenCVStream>(this.OpenCVKey);
if (stream == null)
return null;
return stream.PropertyInfos;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment