Commit 42e844ad by liulongfei

添加预览,添加新滤波函数

parent 8e985ca3
......@@ -35,5 +35,20 @@ namespace VIZ.H2V.Domain
/// 主视图
/// </summary>
public const string MainView = "MainView";
/// <summary>
/// 预览 1
/// </summary>
public const string Preview_1 = "Preview_1";
/// <summary>
/// 预览 2
/// </summary>
public const string Preview_2 = "Preview_2";
/// <summary>
/// 预览 3
/// </summary>
public const string Preview_3 = "Preview_3";
}
}
......@@ -32,6 +32,21 @@ namespace VIZ.H2V.Domain
public const string CAM_4 = "CAM4";
/// <summary>
/// 预览 1
/// </summary>
public const string PREVIEW_1 = "PREVIEW_1";
/// <summary>
/// 预览 2
/// </summary>
public const string PREVIEW_2 = "PREVIEW_2";
/// <summary>
/// 预览 3
/// </summary>
public const string PREVIEW_3 = "PREVIEW_3";
/// <summary>
/// 视频控制
/// </summary>
public const string VideoControl = "VideoControl";
......
......@@ -79,7 +79,24 @@
</Grid.ColumnDefinitions>
<local:NDIView x:Name="cam2" NDIKey="{x:Static Member=domain:NDIViewKeys.CAM_2}" Grid.Row="0" Grid.Column="1" Margin="15,10,10,10"></local:NDIView>
<local:NDIView x:Name="cam3" NDIKey="{x:Static Member=domain:NDIViewKeys.CAM_3}" Grid.Row="1" Grid.Column="0" Margin="10,10,15,10"></local:NDIView>
<local:NDIView x:Name="cam4" NDIKey="{x:Static Member=domain:NDIViewKeys.CAM_4}" Grid.Row="1" Grid.Column="1" Margin="15,10,10,10"></local:NDIView>
<!-- ***************************************************************************************** -->
<!--<local:NDIView x:Name="cam4" NDIKey="{x:Static Member=domain:NDIViewKeys.CAM_4}" Grid.Row="1" Grid.Column="1" Margin="15,10,10,10"></local:NDIView>-->
<!-- ***************************************************************************************** -->
<!-- CAM_4 窗口暂时隐藏,改为放置3个预览窗口 -->
<Grid Grid.Row="1" Grid.Column="1" Margin="20,80,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<local:NDIPreviewView x:Name="prevew1" NDIKey="{x:Static Member=domain:NDIViewKeys.Preview_1}"
Grid.Column="0" Margin="0,0,10,0"></local:NDIPreviewView>
<local:NDIPreviewView x:Name="prevew2" NDIKey="{x:Static Member=domain:NDIViewKeys.Preview_2}"
Grid.Column="1" Margin="5,0,5,0"></local:NDIPreviewView>
<local:NDIPreviewView x:Name="prevew3" NDIKey="{x:Static Member=domain:NDIViewKeys.Preview_3}"
Grid.Column="2" Margin="10,0,0,0"></local:NDIPreviewView>
</Grid>
<!-- ***************************************************************************************** -->
<!-- CAM_1 会作为单一窗口时的主窗口 -->
<local:NDIView x:Name="cam1" NDIKey="{x:Static Member=domain:NDIViewKeys.CAM_1}" Grid.Row="0" Grid.Column="0" Margin="10,10,15,10"></local:NDIView>
</Grid>
......
<UserControl x:Class="VIZ.H2V.Module.NDIPreviewView"
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:behaviors="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:VIZ.H2V.Module"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=local:NDIPreviewViewModel}"
d:DesignHeight="1920" d:DesignWidth="1080">
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="Loaded">
<behaviors:InvokeCommandAction Command="{Binding LoadedCommand}" />
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
<Border BorderBrush="#22ffffff" BorderThickness="1">
<fcommon:VideoControl x:Name="video"></fcommon:VideoControl>
</Border>
</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>
/// NDIPreviewView.xaml 的交互逻辑
/// </summary>
public partial class NDIPreviewView : UserControl
{
public NDIPreviewView()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new NDIPreviewViewModel());
this.video.IsShowFPS = ApplicationDomainEx.IniStorage.GetValue<VideoConfig, bool>(p => p.VIDEO_IS_SHOW_FPS);
}
#region NDIKey -- NDI
/// <summary>
/// NDI键
/// </summary>
public string NDIKey
{
get { return (string)GetValue(NDIKeyProperty); }
set { SetValue(NDIKeyProperty, value); }
}
/// <summary>
/// Using a DependencyProperty as the backing store for NDIKey. This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty NDIKeyProperty =
DependencyProperty.Register("NDIKey", typeof(string), typeof(NDIPreviewView), 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.H2V.Domain;
namespace VIZ.H2V.Module
{
/// <summary>
/// NDI预览视图模型
/// </summary>
public class NDIPreviewViewModel : ViewModelBase
{
public NDIPreviewViewModel()
{
// 初始化命令
this.InitCommand();
}
/// <summary>
/// 初始化命令
/// </summary>
private void InitCommand()
{
this.LoadedCommand = new VCommand(this.Loaded);
}
// ======================================================================================
// === Property ===
// ======================================================================================
#region ViewKey -- NDI视图键
private string viewKey;
/// <summary>
/// NDI视图键
/// <see cref="NDIViewKeys"/>
/// </summary>
/// <remarks>
/// 4个视图窗口分别对应 CAM_1、CAM_2、CAM_3、CAM_4
/// 4个视图窗口UDP键对应 CAM_1、CAM_2、CAM_3、CAM_4
/// 4个视图窗口裁切UDP键对应 CAM_1__CLIP、CAM_2__CLIP、CAM_3__CLIP、CAM_4__CLIP
/// 3个预览窗口分别对应.......Preview_1、Preview_2、Preview_3
/// </remarks>
public string ViewKey
{
get { return viewKey; }
set { viewKey = value; this.RaisePropertyChanged(nameof(ViewKey)); }
}
#endregion
// ======================================================================================
// === Command ===
// ======================================================================================
#region LoadedCommand -- 加载命令
/// <summary>
/// 加载命令
/// </summary>
public VCommand LoadedCommand { get; set; }
/// <summary>
/// 加载
/// </summary>
private void Loaded()
{
if (this.IsAlreadyLoaded)
return;
this.IsAlreadyLoaded = true;
NDIPreviewView view = this.GetView<NDIPreviewView>();
if (view == null)
return;
// 视图键
this.ViewKey = view.NDIKey;
NDIStream nDIStream = VideoStreamManager.Get<NDIStream>(this.ViewKey);
nDIStream.ExecuteVideoFrame -= NDIStream_ExecuteVideoFrame;
nDIStream.ExecuteVideoFrame += NDIStream_ExecuteVideoFrame;
nDIStream.Start();
}
#endregion
// ======================================================================================
// === Private Function ===
// ======================================================================================
/// <summary>
/// 处理视频流
/// </summary>
private void NDIStream_ExecuteVideoFrame(object sender, VideoFrameEventArgs e)
{
NDIPreviewView view = this.GetView<NDIPreviewView>();
if (view == null)
return;
view.video.UpdateVideoFrame(e.Frame);
}
}
}
......@@ -41,5 +41,13 @@ namespace VIZ.H2V.Module
/// </summary>
/// <param name="clipX">剪切X值</param>
void Reset(double clipX);
/// <summary>
/// 获取 Savitzky Golay 算法值
/// </summary>
/// <param name="timeCode">时码</param>
/// <param name="value">值</param>
/// <returns>Savitzky Golay 算法值</returns>
Navigation3DSmoothWithSavitzkyGolayResult GetSavitzkyGolayValue(long timeCode, double value);
}
}
......@@ -43,6 +43,11 @@ namespace VIZ.H2V.Module
public Navigation3DSmooth ClipBoxSmooth { get; private set; } = new Navigation3DSmooth();
/// <summary>
/// 使用 Savitzky Golay 滤波器的算法
/// </summary>
public Navigation3DSmoothWithSavitzkyGolay ClipBoxSmoothWithSavitzkyGolay = new Navigation3DSmoothWithSavitzkyGolay(201, 2, 201);
/// <summary>
/// 裁切框目标X坐标
/// </summary>
public double ClipBoxTargetX { get; set; } = (ApplicationDomainEx.VIDEO_WIDTH - ApplicationDomainEx.VIDEO_CLIP_BOX_WIDTH) / 2;
......@@ -53,6 +58,17 @@ namespace VIZ.H2V.Module
public IManualSupport Support { get; private set; }
/// <summary>
/// 获取 Savitzky Golay 算法值
/// </summary>
/// <param name="timeCode">时码</param>
/// <param name="value">值</param>
/// <returns>Savitzky Golay 算法值</returns>
public Navigation3DSmoothWithSavitzkyGolayResult GetSavitzkyGolayValue(long timeCode, double value)
{
return this.ClipBoxSmoothWithSavitzkyGolay.Smooth(timeCode, value);
}
/// <summary>
/// 获取计算值
/// </summary>
/// <param name="min">最小值</param>
......@@ -74,7 +90,6 @@ namespace VIZ.H2V.Module
// 其他情况不处理
return this.ClipBoxTargetX;
}
/// <summary>
......
......@@ -127,6 +127,9 @@ namespace VIZ.H2V.Module
this.UpdateClipBoxWithManualAndCenter();
}
// 获取将要发送的裁切数据, 无论什么模式均要发送
Navigation3DSmoothWithSavitzkyGolayResult sendValue = this.ManualController.GetSavitzkyGolayValue(e.Frame.TimeStamp, this.ClipBoxX + ApplicationDomainEx.VIDEO_CLIP_BOX_WIDTH / 2);
// 如果当前模式为手动模式或居中模式且处于接收裁切信号状态,并且需要进行裁切,那么发送手动裁切信号
if (e.Frame != null && this.ViewStatus == NDIViewStatus.CropRoi && this.IsUseClip
&& (this.StrategyMode == AlgorithmStrategyMode.center_mode || this.StrategyMode == AlgorithmStrategyMode.manual_mode))
......@@ -153,7 +156,7 @@ namespace VIZ.H2V.Module
UdpEndpointManager manager_clip = ConnectionManager.UdpConnection.GetEndpointManager($"{this.ViewKey}__CLIP");
if (manager_clip != null)
{
ClipSender.CropRoi(manager_clip, 0, roi, ApplicationDomainEx.VIDEO_CLIP_BOX_WIDTH, e.Frame.Height, e.Frame.TimeStamp);
ClipSender.CropRoi(manager_clip, 0, this.GetManulRoi((int)sendValue.Value), ApplicationDomainEx.VIDEO_CLIP_BOX_WIDTH, e.Frame.Height, sendValue.TimeCode);
}
}
}
......
......@@ -241,6 +241,21 @@ namespace VIZ.H2V.Module
}
/// <summary>
/// 获取手动裁切框
/// </summary>
/// <param name="center">中心值</param>
/// <returns>手动裁切框</returns>
public List<int> GetManulRoi(int center)
{
int left = center - ApplicationDomainEx.VIDEO_CLIP_BOX_WIDTH / 2;
int top = 0;
int right = center + ApplicationDomainEx.VIDEO_CLIP_BOX_WIDTH / 2;
int bottom = 1080;
return new List<int> { left, top, right, bottom };
}
/// <summary>
/// 清理视频控件
/// </summary>
/// <param name="context">清理视频控件上下文</param>
......
......@@ -67,6 +67,23 @@ namespace VIZ.H2V.Module
NDIStream ndiStream4 = new NDIStream(localrecvname, config4?.StreamName, option4);
VideoStreamManager.Append(NDIViewKeys.CAM_4, ndiStream4);
SystemConfig systemConfig = ApplicationDomainEx.LiteDbContext.SystemConfig.FindAll().FirstOrDefault();
// Preview 1
NDIStreamOption optionP1 = new NDIStreamOption() { Rotation = OpenCvSharp.RotateFlags.Rotate90Counterclockwise };
NDIStream ndiPreview1 = new NDIStream(localrecvname, systemConfig?.PreviewStreamName1, optionP1);
VideoStreamManager.Append(NDIViewKeys.Preview_1, ndiPreview1);
// Preview 2
NDIStreamOption optionP2 = new NDIStreamOption() { Rotation = OpenCvSharp.RotateFlags.Rotate90Counterclockwise };
NDIStream ndiPreview2 = new NDIStream(localrecvname, systemConfig?.PreviewStreamName2, optionP2);
VideoStreamManager.Append(NDIViewKeys.Preview_2, ndiPreview2);
// Preview 1
NDIStreamOption optionP3 = new NDIStreamOption() { Rotation = OpenCvSharp.RotateFlags.Rotate90Counterclockwise };
NDIStream ndiPreview3 = new NDIStream(localrecvname, systemConfig?.PreviewStreamName3, optionP3);
VideoStreamManager.Append(NDIViewKeys.Preview_3, ndiPreview3);
return true;
}
......
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
using VIZ.H2V.Domain;
namespace VIZ.H2V.Module
{
/// <summary>
/// NDI流选择模型
/// </summary>
public class NDIStreamSelectionModel : ModelBase
{
#region NDIStreamInfos -- NDI流信息
private List<NDIStreamInfoModel> nDIStreamInfos;
/// <summary>
/// NDI流信息
/// </summary>
public List<NDIStreamInfoModel> NDIStreamInfos
{
get { return nDIStreamInfos; }
set { nDIStreamInfos = value; this.RaisePropertyChanged(nameof(NDIStreamInfos)); }
}
#endregion
#region NDIStreamInfosView -- NDI流信息视图
private ICollectionView ndiStreamInfosView;
/// <summary>
/// NDI流信息视图
/// </summary>
public ICollectionView NDIStreamInfosView
{
get { return ndiStreamInfosView; }
set { ndiStreamInfosView = value; this.RaisePropertyChanged(nameof(NDIStreamInfosView)); }
}
#endregion
#region SelectedNDIStreamInfo -- 选中的NDI流信息
private NDIStreamInfoModel selectedNDIStreamInfo;
/// <summary>
/// 选中的NDI流信息
/// </summary>
public NDIStreamInfoModel SelectedNDIStreamInfo
{
get { return selectedNDIStreamInfo; }
set { selectedNDIStreamInfo = value; this.RaisePropertyChanged(nameof(SelectedNDIStreamInfo)); }
}
#endregion
}
}
<UserControl x:Class="VIZ.H2V.Module.PreviewSettingPanelView"
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"
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
xmlns:toolkit="http://schemas.xceed.com/wpf/xaml/toolkit"
d:DataContext="{d:DesignInstance Type=local:PreviewSettingPanelViewModel}"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/VIZ.H2V.Module.Resource;component/Style/ComboBox/ComboBox_Setting.xaml"></ResourceDictionary>
<ResourceDictionary Source="/VIZ.H2V.Module.Resource;component/Style/Button/Button_Setting.xaml"></ResourceDictionary>
<ResourceDictionary Source="/VIZ.H2V.Module.Resource;component/Style/TextBox/TextBox_Setting.xaml"></ResourceDictionary>
<ResourceDictionary Source="/VIZ.H2V.Module.Resource;component/Style/TextBox/TextBox_Setting.xaml"></ResourceDictionary>
<ResourceDictionary Source="/VIZ.H2V.Module.Resource;component/Style/CheckBox/CheckBox_Setting.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:Key="NDI_ItemTemplate">
<Border Background="Transparent" IsHitTestVisible="False">
<TextBlock Text="{Binding Path=FullName}" Foreground="White" FontSize="16"></TextBlock>
</Border>
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="Loaded">
<behaviors:InvokeCommandAction Command="{Binding LoadedCommand}" />
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
<Border>
<Grid Margin="45,60,40,0" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<!-- 输入源 -->
<TextBlock Text="视频输入" Foreground="White" FontSize="18" VerticalAlignment="Center"></TextBlock>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right">
<TextBlock Text="仅显示本机视频输入" Foreground="#aaffffff" VerticalAlignment="Center"></TextBlock>
<CheckBox Style="{StaticResource CheckBox_Setting}" VerticalAlignment="Center"
HorizontalAlignment="Right" Margin="10,0,0,0"
IsChecked="{Binding Path=IsShowLocalStream,Mode=TwoWay}"></CheckBox>
</StackPanel>
<!-- Preview 1 -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="预览 1" Foreground="#AAFFFFFF" FontSize="20" VerticalAlignment="Center" Grid.Row="8"></TextBlock>
<ComboBox Grid.Column="1" Style="{StaticResource ComboBox_Setting}" Height="40"
ItemTemplate="{StaticResource NDI_ItemTemplate}"
ItemsSource="{Binding Path=Preview_1.NDIStreamInfosView,Mode=OneWay}"
SelectedValue="{Binding Path=Preview_1.SelectedNDIStreamInfo,Mode=TwoWay}">
</ComboBox>
</Grid>
<!-- Preview 2 -->
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="预览 2" Foreground="#AAFFFFFF" FontSize="20" VerticalAlignment="Center" Grid.Row="8"></TextBlock>
<ComboBox Grid.Column="1" Style="{StaticResource ComboBox_Setting}" Height="40"
ItemTemplate="{StaticResource NDI_ItemTemplate}"
ItemsSource="{Binding Path=Preview_2.NDIStreamInfosView,Mode=OneWay}"
SelectedValue="{Binding Path=Preview_2.SelectedNDIStreamInfo,Mode=TwoWay}">
</ComboBox>
</Grid>
<!-- Preview 3 -->
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="预览 3" Foreground="#AAFFFFFF" FontSize="20" VerticalAlignment="Center" Grid.Row="8"></TextBlock>
<ComboBox Grid.Column="1" Style="{StaticResource ComboBox_Setting}" Height="40"
ItemTemplate="{StaticResource NDI_ItemTemplate}"
ItemsSource="{Binding Path=Preview_3.NDIStreamInfosView,Mode=OneWay}"
SelectedValue="{Binding Path=Preview_3.SelectedNDIStreamInfo,Mode=TwoWay}">
</ComboBox>
</Grid>
</Grid>
</Border>
</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>
/// PreviewSettingPanelView.xaml 的交互逻辑
/// </summary>
public partial class PreviewSettingPanelView : UserControl
{
public PreviewSettingPanelView()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new PreviewSettingPanelViewModel());
}
}
}
......@@ -47,6 +47,8 @@
x:Name="rbHotkey" Style="{StaticResource RadioButton_Setting}"></RadioButton>
<RadioButton Content="Tally" Height="50" Foreground="White" FontSize="22" VerticalContentAlignment="Center"
x:Name="rbTally" Style="{StaticResource RadioButton_Setting}"></RadioButton>
<RadioButton Content="预览" Height="50" Foreground="White" FontSize="22" VerticalContentAlignment="Center"
x:Name="rbPreview" Style="{StaticResource RadioButton_Setting}"></RadioButton>
<RadioButton Content="关于" Height="50" Foreground="White" FontSize="22" VerticalContentAlignment="Center"
x:Name="rbAbout" Style="{StaticResource RadioButton_Setting}"></RadioButton>
</StackPanel>
......@@ -61,6 +63,8 @@
IsSelected="{Binding ElementName=rbHotkey,Path=IsChecked,Mode=OneWay}"></fcommon:NavigationItemControl>
<fcommon:NavigationItemControl ViewType="{x:Type local:TallySettingPanelView}"
IsSelected="{Binding ElementName=rbTally,Path=IsChecked,Mode=OneWay}"></fcommon:NavigationItemControl>
<fcommon:NavigationItemControl ViewType="{x:Type local:PreviewSettingPanelView}"
IsSelected="{Binding ElementName=rbPreview,Path=IsChecked,Mode=OneWay}"></fcommon:NavigationItemControl>
<fcommon:NavigationItemControl ViewType="{x:Type local:AboutPanelView}"
IsSelected="{Binding ElementName=rbAbout,Path=IsChecked,Mode=OneWay}"></fcommon:NavigationItemControl>
</fcommon:NavigationControl>
......
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using VIZ.Framework.Common;
using VIZ.Framework.Core;
using VIZ.H2V.Domain;
using VIZ.H2V.Storage;
namespace VIZ.H2V.Module
{
/// <summary>
/// 预览设置面板视图模型
/// </summary>
public class PreviewSettingPanelViewModel : ViewModelBase, ISystemSetting
{
public PreviewSettingPanelViewModel()
{
this.LoadedCommand = new VCommand(this.Loaded);
}
// ======================================================================================
// === Field ===
// ======================================================================================
/// <summary>
/// 系统设置
/// </summary>
private SystemConfig SystemConfig;
// ======================================================================================
// === Property ===
// ======================================================================================
#region IsShowLocalStream -- 是否显示本地流
private bool isShowLocalStream;
/// <summary>
/// 是否显示本地流
/// </summary>
public bool IsShowLocalStream
{
get { return isShowLocalStream; }
set
{
isShowLocalStream = value;
this.RaisePropertyChanged(nameof(IsShowLocalStream));
this.Preview_1.NDIStreamInfosView.Refresh();
this.Preview_2.NDIStreamInfosView.Refresh();
this.Preview_3.NDIStreamInfosView.Refresh();
}
}
#endregion
#region Preview_1 -- 预览 1
private NDIStreamSelectionModel preview_1 = new NDIStreamSelectionModel();
/// <summary>
/// 预览 1
/// </summary>
public NDIStreamSelectionModel Preview_1
{
get { return preview_1; }
set { preview_1 = value; this.RaisePropertyChanged(nameof(Preview_1)); }
}
#endregion
#region Preview_2 -- 预览 2
private NDIStreamSelectionModel preview_2 = new NDIStreamSelectionModel();
/// <summary>
/// 预览 2
/// </summary>
public NDIStreamSelectionModel Preview_2
{
get { return preview_2; }
set { preview_2 = value; this.RaisePropertyChanged(nameof(Preview_2)); }
}
#endregion
#region Preview_3 -- 预览 3
private NDIStreamSelectionModel preview_3 = new NDIStreamSelectionModel();
/// <summary>
/// 预览 3
/// </summary>
public NDIStreamSelectionModel Preview_3
{
get { return preview_3; }
set { preview_3 = value; this.RaisePropertyChanged(nameof(Preview_3)); }
}
#endregion
// ======================================================================================
// === Commond ===
// ======================================================================================
#region LoadedCommand -- 加载命令
/// <summary>
/// 加载命令
/// </summary>
public VCommand LoadedCommand { get; set; }
/// <summary>
/// 加载
/// </summary>
private void Loaded()
{
SystemSettingViewModel vm = WPFHelper.GetAncestorByType<SystemSettingView>(this.GetView<FrameworkElement>()).DataContext as SystemSettingViewModel;
vm.Settings.Add(this);
this.SystemConfig = vm.SystemConfig;
this.LoadNdiStreamInfo(NDIViewKeys.Preview_1, this.Preview_1);
this.LoadNdiStreamInfo(NDIViewKeys.Preview_2, this.Preview_2);
this.LoadNdiStreamInfo(NDIViewKeys.Preview_3, this.Preview_3);
}
#endregion
/// <summary>
/// 加载NDI流信息
/// </summary>
/// <param name="viewKey">视图键</param>
/// <param name="selectionModel">NDI流选择模型</param>
private void LoadNdiStreamInfo(string viewKey, NDIStreamSelectionModel selectionModel)
{
NDIStream ndiStream = VideoStreamManager.Get<NDIStream>(viewKey);
List<NDIStreamInfoModel> list = new List<NDIStreamInfoModel>();
NDIStreamInfoModel none = new NDIStreamInfoModel();
list.Add(none);
NDIStreamInfoModel selected = none;
if (ndiStream.StreamInfos != null && ndiStream.StreamInfos.Count > 0)
{
string localName = System.Net.Dns.GetHostName();
foreach (NDIStreamInfo info in ndiStream.StreamInfos)
{
NDIStreamInfoModel model = new NDIStreamInfoModel();
model.FullName = info.FullName;
model.Address = info.Address;
model.IsLocalStream = info.Machine == localName;
if (model.FullName == ndiStream.RemoteSenderName)
{
selected = model;
}
list.Add(model);
}
}
none.IsLocalStream = true;
selectionModel.NDIStreamInfos = list;
selectionModel.NDIStreamInfosView = CollectionViewSource.GetDefaultView(selectionModel.NDIStreamInfos);
selectionModel.NDIStreamInfosView.Filter = o => this.NDIStreamInfosViewFilter(o as NDIStreamInfoModel);
selectionModel.SelectedNDIStreamInfo = selected;
}
/// <summary>
/// NDI流视图筛选器
/// </summary>
/// <param name="model">NDI流模型</param>
/// <returns>是否通过筛选</returns>
private bool NDIStreamInfosViewFilter(NDIStreamInfoModel model)
{
if (model == null)
return true;
if (!this.IsShowLocalStream)
return true;
return model.IsLocalStream;
}
/// <summary>
/// 是否需要保存
/// </summary>
/// <returns>是否需要保存</returns>
public bool IsNeedSave()
{
if (this.SystemConfig.PreviewStreamName1 != this.Preview_1.SelectedNDIStreamInfo?.FullName)
return true;
if (this.SystemConfig.PreviewStreamName2 != this.Preview_2.SelectedNDIStreamInfo?.FullName)
return true;
if (this.SystemConfig.PreviewStreamName3 != this.Preview_3.SelectedNDIStreamInfo?.FullName)
return true;
return false;
}
/// <summary>
/// 保存
/// </summary>
/// <returns>是否成功保存</returns>
public bool Save()
{
this.SystemConfig.PreviewStreamName1 = this.Preview_1.SelectedNDIStreamInfo?.FullName;
this.SystemConfig.PreviewStreamName2 = this.Preview_2.SelectedNDIStreamInfo?.FullName;
this.SystemConfig.PreviewStreamName3 = this.Preview_3.SelectedNDIStreamInfo?.FullName;
ApplicationDomainEx.LiteDbContext.SystemConfig.Update(this.SystemConfig);
VideoStreamManager.Get<NDIStream>(NDIViewKeys.Preview_1)?.ChangeRemoteSenderName(this.SystemConfig.PreviewStreamName1);
VideoStreamManager.Get<NDIStream>(NDIViewKeys.Preview_2)?.ChangeRemoteSenderName(this.SystemConfig.PreviewStreamName2);
VideoStreamManager.Get<NDIStream>(NDIViewKeys.Preview_3)?.ChangeRemoteSenderName(this.SystemConfig.PreviewStreamName3);
return true;
}
/// <summary>
/// 取消
/// </summary>
public void Cancel()
{
}
}
}
......@@ -132,6 +132,10 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Page Include="NDIPreviewView\View\NDIPreviewView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="NDISettingView\View\Algorithm\AlgorithmNearPanelView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
......@@ -152,6 +156,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="SystemSetting\View\PreviewSettingPanelView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="SystemSetting\View\AboutPanelView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
......@@ -205,6 +213,10 @@
<Compile Include="NDIMainView\Controller\Loop\ILoopSupport.cs" />
<Compile Include="NDIMainView\Controller\Loop\LoopController.cs" />
<Compile Include="NDIMainView\Service\INDIMainViewService.cs" />
<Compile Include="NDIPreviewView\ViewModel\NDIPreviewViewModel.cs" />
<Compile Include="NDIPreviewView\View\NDIPreviewView.xaml.cs">
<DependentUpon>NDIPreviewView.xaml</DependentUpon>
</Compile>
<Compile Include="NDISettingView\ViewModel\Algorithm\AlgorithmCablewayPanelViewModel.cs" />
<Compile Include="NDISettingView\ViewModel\Algorithm\AlgorithmTacticsPanelViewModel.cs" />
<Compile Include="NDISettingView\ViewModel\INDISetting.cs" />
......@@ -240,6 +252,11 @@
<Compile Include="NDIView\VieweModel\Part\NDIViewTallyPartViewModel.cs" />
<Compile Include="NDIView\VieweModel\Part\NDIViewToolPartViewModel.cs" />
<Compile Include="Permissions\PermissionsCheck.cs" />
<Compile Include="SystemSetting\Model\NDIStreamSelectionModel.cs" />
<Compile Include="SystemSetting\ViewModel\PreviewSettingPanelViewModel.cs" />
<Compile Include="SystemSetting\View\PreviewSettingPanelView.xaml.cs">
<DependentUpon>PreviewSettingPanelView.xaml</DependentUpon>
</Compile>
<Compile Include="Setup\Provider\AppSetup_GPIO2USB.cs" />
<Compile Include="Setup\Provider\AppSetup_Navigation3DConfig.cs" />
<Compile Include="Setup\Provider\AppSetup_Algorithm.cs" />
......
......@@ -104,5 +104,20 @@ namespace VIZ.H2V.Storage
/// Tally信息 -- 窗口4
/// </summary>
public TallyInfo TallyInfo4 { get; set; } = new TallyInfo();
/// <summary>
/// 预览流 1
/// </summary>
public string PreviewStreamName1 { get; set; }
/// <summary>
/// 预览流 2
/// </summary>
public string PreviewStreamName2 { get; set; }
/// <summary>
/// 预览流 3
/// </summary>
public string PreviewStreamName3 { get; set; }
}
}
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