-
Notifications
You must be signed in to change notification settings - Fork 6
GWP desktop player sample #171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
alafleur-genetec
wants to merge
9
commits into
main
Choose a base branch
from
feat/gwp-desktop-player-sample
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
22aaccf
feat: add GWP desktop player sample
alafleur-genetec 83ea478
Update TokenProvider.cs
alafleur-genetec db76671
Update App.xaml
alafleur-genetec d1c5c00
Update MainWindow.xaml
alafleur-genetec 1812fdc
fix: explicitly disable DevTools in Release builds
alafleur-genetec 4dc0050
fix: move DevTools button visibility toggle to code-behind
alafleur-genetec 48006b3
fix: remove Player surface label from stage header
alafleur-genetec e8f15fa
fix: clean up leaked player on failed start and widen cert bypass
alafleur-genetec abb1b28
docs: remove filler 'Why this shape' section from desktop sample README
alafleur-genetec File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <Application x:Class="Genetec.Dap.CodeSamples.App" | ||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
| StartupUri="MainWindow.xaml"> | ||
| <Application.Resources> | ||
|
|
||
| </Application.Resources> | ||
| </Application> |
11 changes: 11 additions & 0 deletions
11
Samples/Genetec Web Player/GwpDesktopPlayerSample/App.xaml.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // Copyright 2025 Genetec Inc. | ||
| // Licensed under the Apache License, Version 2.0 | ||
|
|
||
| using System.Windows; | ||
|
|
||
| namespace Genetec.Dap.CodeSamples; | ||
|
|
||
| public partial class App : Application | ||
| { | ||
| } | ||
|
|
13 changes: 13 additions & 0 deletions
13
Samples/Genetec Web Player/GwpDesktopPlayerSample/AssemblyInfo.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // Copyright 2025 Genetec Inc. | ||
| // Licensed under the Apache License, Version 2.0 | ||
|
|
||
| using System.Windows; | ||
|
|
||
| [assembly:ThemeInfo( | ||
| ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located | ||
| //(used if a resource is not found in the page, | ||
| // or application resource dictionaries) | ||
| ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located | ||
| //(used if a resource is not found in the page, | ||
| // app, or any theme specific resource dictionaries) | ||
| )] |
26 changes: 26 additions & 0 deletions
26
Samples/Genetec Web Player/GwpDesktopPlayerSample/GwpDesktopPlayerSample.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>WinExe</OutputType> | ||
| <TargetFramework>net8.0-windows</TargetFramework> | ||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <UseWPF>true</UseWPF> | ||
| <AssemblyName>GwpDesktopPlayerSample</AssemblyName> | ||
| <RootNamespace>Genetec.Dap.CodeSamples</RootNamespace> | ||
| <Description>Sample project</Description> | ||
| <Company>Genetec Inc.</Company> | ||
| <Copyright>Copyright © Genetec Inc. 2025</Copyright> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3240.44" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <Content Include="wwwroot\**\*"> | ||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
| </Content> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
91 changes: 91 additions & 0 deletions
91
Samples/Genetec Web Player/GwpDesktopPlayerSample/MainWindow.xaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| <Window x:Class="Genetec.Dap.CodeSamples.MainWindow" | ||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
| xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" | ||
| mc:Ignorable="d" | ||
| Title="GWP Desktop Player Sample" | ||
| Height="900" | ||
| Width="1440" | ||
| MinHeight="720" | ||
| MinWidth="1100"> | ||
| <DockPanel> | ||
| <Border DockPanel.Dock="Top" | ||
| Padding="12" | ||
| Background="#0B172A" | ||
| BorderBrush="#17324F" | ||
| BorderThickness="0,0,0,1"> | ||
| <Grid> | ||
| <Grid.ColumnDefinitions> | ||
| <ColumnDefinition Width="*" /> | ||
| <ColumnDefinition Width="Auto" /> | ||
| <ColumnDefinition Width="Auto" /> | ||
| </Grid.ColumnDefinitions> | ||
|
|
||
| <TextBlock x:Name="StatusTextBlock" | ||
| VerticalAlignment="Center" | ||
| Text="Initializing WebView2..." | ||
| Foreground="#B7C6D8" /> | ||
|
|
||
| <StackPanel Grid.Column="1" | ||
| Margin="20,0,16,0" | ||
| VerticalAlignment="Center"> | ||
| <TextBlock Text="Security Center Authentication" | ||
| FontSize="12" | ||
| FontWeight="SemiBold" | ||
| Foreground="#F5F7FA" /> | ||
| <StackPanel Margin="0,6,0,0" | ||
| Orientation="Horizontal"> | ||
| <StackPanel> | ||
| <TextBlock Text="Username" | ||
| FontSize="11" | ||
| Foreground="#B7C6D8" /> | ||
| <TextBox x:Name="UsernameTextBox" | ||
| Width="170" | ||
| Margin="0,4,8,0" | ||
| Padding="8,4" | ||
| TextChanged="UsernameTextBox_TextChanged" /> | ||
| </StackPanel> | ||
| <StackPanel> | ||
| <TextBlock Text="Password" | ||
| FontSize="11" | ||
| Foreground="#B7C6D8" /> | ||
| <PasswordBox x:Name="PasswordBox" | ||
| Width="170" | ||
| Margin="0,4,0,0" | ||
| Padding="8,4" | ||
| PasswordChanged="PasswordBox_PasswordChanged" /> | ||
| </StackPanel> | ||
| </StackPanel> | ||
| <StackPanel Margin="0,8,0,0"> | ||
| <TextBlock Text="SDK Certificate" | ||
| FontSize="11" | ||
| Foreground="#B7C6D8" /> | ||
| <TextBox x:Name="SdkCertificateTextBox" | ||
| Width="348" | ||
| Margin="0,4,0,0" | ||
| Padding="8,4" | ||
| TextChanged="SdkCertificateTextBox_TextChanged" /> | ||
| </StackPanel> | ||
| </StackPanel> | ||
|
|
||
| <StackPanel Grid.Column="2" | ||
| Orientation="Horizontal" | ||
| VerticalAlignment="Center"> | ||
| <Button x:Name="RefreshButton" | ||
| Margin="0,0,8,0" | ||
| Padding="14,8" | ||
| Click="RefreshButton_Click" | ||
| Content="Refresh" /> | ||
| <Button x:Name="DevToolsButton" | ||
| Padding="14,8" | ||
| Click="DevToolsButton_Click" | ||
| Content="DevTools" /> | ||
| </StackPanel> | ||
| </Grid> | ||
| </Border> | ||
|
|
||
| <wv2:WebView2 x:Name="Browser" /> | ||
| </DockPanel> | ||
| </Window> |
157 changes: 157 additions & 0 deletions
157
Samples/Genetec Web Player/GwpDesktopPlayerSample/MainWindow.xaml.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| // Copyright 2025 Genetec Inc. | ||
| // Licensed under the Apache License, Version 2.0 | ||
|
|
||
| using System; | ||
| using System.IO; | ||
| using System.Text.Json; | ||
| using System.Windows; | ||
| using System.Windows.Controls; | ||
| using System.Windows.Input; | ||
| using Microsoft.Web.WebView2.Core; | ||
|
|
||
| namespace Genetec.Dap.CodeSamples; | ||
|
|
||
| public partial class MainWindow : Window | ||
| { | ||
| private static readonly Uri s_appUri = new("https://app.local/index.html"); | ||
|
|
||
| private NativePlaybackConfiguration? m_playbackConfiguration; | ||
| private TokenProvider? m_tokenProvider; | ||
|
|
||
| public MainWindow() | ||
| { | ||
| InitializeComponent(); | ||
| #if !DEBUG | ||
| DevToolsButton.Visibility = Visibility.Collapsed; | ||
| #endif | ||
| Loaded += OnLoaded; | ||
| Closed += OnClosed; | ||
| PreviewKeyDown += OnPreviewKeyDown; | ||
| } | ||
|
|
||
| private async void OnLoaded(object sender, RoutedEventArgs e) | ||
| { | ||
| try | ||
| { | ||
| var webRoot = Path.Combine(AppContext.BaseDirectory, "wwwroot"); | ||
| m_playbackConfiguration = NativePlaybackConfiguration.LoadFromEnvironment(); | ||
| UsernameTextBox.Text = m_playbackConfiguration.Username; | ||
| PasswordBox.Password = m_playbackConfiguration.Password; | ||
| SdkCertificateTextBox.Text = m_playbackConfiguration.SdkCertificate; | ||
| m_tokenProvider = new TokenProvider(m_playbackConfiguration); | ||
|
|
||
| var userDataFolder = Path.Combine( | ||
| Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), | ||
| "GwpDesktopPlayerSample", | ||
| "WebView2Data"); | ||
| var environment = await CoreWebView2Environment.CreateAsync(userDataFolder: userDataFolder); | ||
|
|
||
| await Browser.EnsureCoreWebView2Async(environment); | ||
| #if DEBUG | ||
| Browser.CoreWebView2.ServerCertificateErrorDetected += OnServerCertificateErrorDetected; | ||
| #endif | ||
| Browser.CoreWebView2.SetVirtualHostNameToFolderMapping( | ||
| "app.local", | ||
| webRoot, | ||
| CoreWebView2HostResourceAccessKind.Allow); | ||
| Browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true; | ||
| #if DEBUG | ||
| Browser.CoreWebView2.Settings.AreDevToolsEnabled = true; | ||
| #else | ||
| Browser.CoreWebView2.Settings.AreDevToolsEnabled = false; | ||
| #endif | ||
| Browser.CoreWebView2.Settings.IsStatusBarEnabled = true; | ||
|
alafleur-genetec marked this conversation as resolved.
|
||
|
|
||
| var bootstrapScript = $"window.__GWP_HOST_CONFIG__ = {JsonSerializer.Serialize(new | ||
| { | ||
| mediaGatewayEndpoint = m_playbackConfiguration.MediaGatewayEndpoint, | ||
| serverVersion = m_playbackConfiguration.ServerVersion, | ||
| })};"; | ||
| await Browser.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(bootstrapScript); | ||
|
|
||
| Browser.CoreWebView2.AddHostObjectToScript("tokenProvider", m_tokenProvider); | ||
| Browser.CoreWebView2.NavigationStarting += OnNavigationStarting; | ||
| Browser.CoreWebView2.NavigationCompleted += OnNavigationCompleted; | ||
| Browser.CoreWebView2.Navigate(s_appUri.ToString()); | ||
| StatusTextBlock.Text = | ||
| $"WebView2 ready. Native playback configuration loaded for {m_playbackConfiguration.MediaGatewayEndpoint}."; | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| StatusTextBlock.Text = "Failed to initialize WebView2."; | ||
| MessageBox.Show(this, exception.ToString(), "WebView2 initialization failed", MessageBoxButton.OK, MessageBoxImage.Error); | ||
| } | ||
| } | ||
|
|
||
| private void OnNavigationStarting(object? sender, CoreWebView2NavigationStartingEventArgs e) | ||
| { | ||
| if (Uri.TryCreate(e.Uri, UriKind.Absolute, out var uri) && uri.Host != s_appUri.Host) | ||
| { | ||
| e.Cancel = true; | ||
| } | ||
|
alafleur-genetec marked this conversation as resolved.
|
||
| } | ||
|
|
||
| private void OnNavigationCompleted(object? sender, CoreWebView2NavigationCompletedEventArgs e) | ||
| { | ||
| StatusTextBlock.Text = e.IsSuccess | ||
| ? "Local GWP host page loaded. Enter a camera GUID to start playback." | ||
| : $"Navigation failed with error {e.WebErrorStatus}."; | ||
| } | ||
|
|
||
| private void OnClosed(object? sender, EventArgs e) | ||
| { | ||
| (m_tokenProvider as IDisposable)?.Dispose(); | ||
| m_tokenProvider = null; | ||
| } | ||
|
|
||
| private void OnServerCertificateErrorDetected(object? sender, CoreWebView2ServerCertificateErrorDetectedEventArgs e) | ||
| { | ||
| e.Action = CoreWebView2ServerCertificateErrorAction.AlwaysAllow; | ||
|
|
||
| if (Uri.TryCreate(e.RequestUri, UriKind.Absolute, out var uri)) | ||
| { | ||
| StatusTextBlock.Text = $"Allowed certificate warning for development endpoint {uri.Host}."; | ||
| } | ||
| } | ||
|
|
||
| private void RefreshButton_Click(object sender, RoutedEventArgs e) | ||
| { | ||
| if (Browser.CoreWebView2 is null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| Browser.Reload(); | ||
| } | ||
|
|
||
| private void UsernameTextBox_TextChanged(object sender, TextChangedEventArgs e) => SyncNativeCredentials(); | ||
|
|
||
| private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) => SyncNativeCredentials(); | ||
|
|
||
| private void SdkCertificateTextBox_TextChanged(object sender, TextChangedEventArgs e) => SyncNativeCredentials(); | ||
|
|
||
| private void DevToolsButton_Click(object sender, RoutedEventArgs e) | ||
| { | ||
| #if DEBUG | ||
| Browser.CoreWebView2?.OpenDevToolsWindow(); | ||
| #endif | ||
| } | ||
|
|
||
| private void OnPreviewKeyDown(object sender, KeyEventArgs e) | ||
| { | ||
| #if DEBUG | ||
| if (e.Key != Key.F12) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| Browser.CoreWebView2?.OpenDevToolsWindow(); | ||
| e.Handled = true; | ||
| #endif | ||
| } | ||
|
|
||
| private void SyncNativeCredentials() | ||
| { | ||
| m_tokenProvider?.UpdateAuthentication(UsernameTextBox.Text, PasswordBox.Password, SdkCertificateTextBox.Text); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.