Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/OpenIPC.Viewer.App/Services/Localizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ private static LangCode DetectSystem()
["CameraEditor.Placeholder.SshPort"] = "22",
["CameraEditor.NoGroup"] = "(no group)",
["CameraEditor.Button.AutoDeriveRtsp"] = "Auto from host",
["CameraEditor.Button.AutoDeriveXmRtsp"] = "XM preset",
["CameraEditor.Tooltip.AutoDeriveXmRtsp"] = "Fill in the RTSP URLs used by XM/Xiongmai (NETSurveillance) cameras",
["CameraEditor.Button.RtspTemplates"] = "Templates ▾",
["CameraEditor.Tooltip.RtspTemplates"] = "Fill in the RTSP URLs used by a specific camera vendor",
["CameraEditor.Button.TestConnection"] = "Test connection",
["CameraEditor.Status.Connecting"] = "Connecting…",
["CameraEditor.Status.OkFormat"] = "OK — {0}x{1}",
Expand Down Expand Up @@ -811,8 +811,8 @@ private static LangCode DetectSystem()
["CameraEditor.Placeholder.SshPort"] = "22",
["CameraEditor.NoGroup"] = "(без группы)",
["CameraEditor.Button.AutoDeriveRtsp"] = "Подставить из хоста",
["CameraEditor.Button.AutoDeriveXmRtsp"] = "Пресет XM",
["CameraEditor.Tooltip.AutoDeriveXmRtsp"] = "Подставить RTSP-адреса камер XM/Xiongmai (NETSurveillance)",
["CameraEditor.Button.RtspTemplates"] = "Шаблоны ▾",
["CameraEditor.Tooltip.RtspTemplates"] = "Подставить RTSP-адреса под конкретного производителя камеры",
["CameraEditor.Button.TestConnection"] = "Проверить",
["CameraEditor.Status.Connecting"] = "Подключение…",
["CameraEditor.Status.OkFormat"] = "OK — {0}x{1}",
Expand Down
38 changes: 32 additions & 6 deletions src/OpenIPC.Viewer.App/ViewModels/Dialogs/CameraEditorViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,43 @@ private void AutoDeriveRtsp()
RtspMainText = $"rtsp://{Host.Trim()}/";
}

// XM/Xiongmai (NETSurveillance) firmware embeds the login in the RTSP path
// and serves main/sub as stream=0/1. Uses the credential fields when set,
// falling back to the stock "admin" + empty password those cameras ship with.
// Vendor RTSP URI templates (camera-editor "Templates" flyout). Fills both
// main/sub from the host field. Credentials ride the RTSP auth handshake
// (the Username/Password fields), so they are NOT embedded in the URI —
// except XM/Xiongmai (NETSurveillance), whose firmware wants the login in
// the path itself; there the fields are used, falling back to the stock
// "admin" + empty password those cameras ship with.
[RelayCommand]
private void AutoDeriveXmRtsp()
private void ApplyRtspTemplate(string vendor)
{
if (string.IsNullOrWhiteSpace(Host)) return;
var host = Host.Trim();
var user = string.IsNullOrWhiteSpace(Username) ? "admin" : Username.Trim();
RtspMainText = $"rtsp://{host}:554/user={user}&password={Password}&channel=1&stream=0.sdp?real_stream";
RtspSubText = $"rtsp://{host}:554/user={user}&password={Password}&channel=1&stream=1.sdp?real_stream";
(RtspMainText, RtspSubText) = vendor switch
{
"openipc" => (
$"rtsp://{host}:554/stream0",
$"rtsp://{host}:554/stream1"),
"xm" => (
$"rtsp://{host}:554/user={user}&password={Password}&channel=1&stream=0.sdp?real_stream",
$"rtsp://{host}:554/user={user}&password={Password}&channel=1&stream=1.sdp?real_stream"),
"hikvision" => (
$"rtsp://{host}:554/Streaming/Channels/101",
$"rtsp://{host}:554/Streaming/Channels/102"),
"dahua" => (
$"rtsp://{host}:554/cam/realmonitor?channel=1&subtype=0",
$"rtsp://{host}:554/cam/realmonitor?channel=1&subtype=1"),
"reolink" => (
$"rtsp://{host}:554/h264Preview_01_main",
$"rtsp://{host}:554/h264Preview_01_sub"),
"tplink" => (
$"rtsp://{host}:554/stream1",
$"rtsp://{host}:554/stream2"),
"uniview" => (
$"rtsp://{host}:554/media/video1",
$"rtsp://{host}:554/media/video2"),
_ => (RtspMainText, RtspSubText),
};
}

[RelayCommand(CanExecute = nameof(CanTestConnection))]
Expand Down
19 changes: 15 additions & 4 deletions src/OpenIPC.Viewer.App/Views/Dialogs/CameraEditorContent.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,24 @@
Padding="0"
FontSize="{StaticResource FontSizeSm}" />
<Button Grid.Column="3"
Content="{Binding [CameraEditor.Button.AutoDeriveXmRtsp], Source={x:Static svc:Localizer.Instance}}"
Command="{Binding AutoDeriveXmRtspCommand}"
ToolTip.Tip="{Binding [CameraEditor.Tooltip.AutoDeriveXmRtsp], Source={x:Static svc:Localizer.Instance}}"
Content="{Binding [CameraEditor.Button.RtspTemplates], Source={x:Static svc:Localizer.Instance}}"
ToolTip.Tip="{Binding [CameraEditor.Tooltip.RtspTemplates], Source={x:Static svc:Localizer.Instance}}"
Background="Transparent"
Foreground="{StaticResource AccentBrush}"
Padding="0"
FontSize="{StaticResource FontSizeSm}" />
FontSize="{StaticResource FontSizeSm}">
<Button.Flyout>
<MenuFlyout Placement="BottomEdgeAlignedRight">
<MenuItem Header="OpenIPC (Majestic)" Command="{Binding ApplyRtspTemplateCommand}" CommandParameter="openipc" />
<MenuItem Header="XM / Xiongmai (NETSurveillance)" Command="{Binding ApplyRtspTemplateCommand}" CommandParameter="xm" />
<MenuItem Header="Hikvision" Command="{Binding ApplyRtspTemplateCommand}" CommandParameter="hikvision" />
<MenuItem Header="Dahua / Amcrest" Command="{Binding ApplyRtspTemplateCommand}" CommandParameter="dahua" />
<MenuItem Header="Reolink" Command="{Binding ApplyRtspTemplateCommand}" CommandParameter="reolink" />
<MenuItem Header="TP-Link (Tapo / VIGI)" Command="{Binding ApplyRtspTemplateCommand}" CommandParameter="tplink" />
<MenuItem Header="Uniview (UNV)" Command="{Binding ApplyRtspTemplateCommand}" CommandParameter="uniview" />
</MenuFlyout>
</Button.Flyout>
</Button>
</Grid>
<TextBox Text="{Binding RtspMainText, Mode=TwoWay}" PlaceholderText="{Binding [CameraEditor.Placeholder.RtspMain], Source={x:Static svc:Localizer.Instance}}" FontFamily="{StaticResource FontMono}" />
</StackPanel>
Expand Down
Loading