Git Product home page Git Product logo

csharp-stream-controller's Introduction

watfordjc

I am John Cook (WatfordJC) and I go through phases of dabbling with turning fleeting thoughts into code, invariably only half finishing the code before losing interest or thinking about something else.

ICD-10 F84.5, F33.1, F32.2

Part of the reason I leave code half finished is because of how my brain works. A lot of people on the autism spectrum have specific interests, but my combination of recurrent depressive disorder and treatment-resistant major depressive disorder mean losing interest in things is my psychological norm.

As a result, I have a wide range of interests, a specific interest for a period of time, and zero interests, depending on mood, meltdowns, anhedonic levels, etc. I am a domain registrar, a record label, a food grower, and the politics section of my Web site still contains my 2010 election manifesto (a week or so before the deadline for submitting nomination papers I was advised not to stand).

I wrote a list of things that didn't interest me one of the recent times I suffered anhedonia, not that I finished the list… maths, accounting, business, politics, sociology, health & fitness, first aid, psychiatry, electronics, radio communications, telecommunications, music production, Internet/Web/e-mail standards/services, video production, cosmology, computers, technology, programming.

Projects and Applications

My Web browser acts a bit like a stack, although with more things being added to it than removed I recently tripled my RAM to avoid a figurative stack overflow. I have about 100 browser windows open and the total number of tabs is likely in the region of 500-2,000.

I do eventually close tabs when I've finished needing the documentation for coding something (or when background workers in Web pages are using too much CPU), though.

The tabs for the Have I Been Pwned? API were closed when I "completed" my Android app Bad Passwd, although I think the Food Standards Agency API tabs I had open when last working on the Android app Food Safety Alerts were open on my now dead laptop so haven't been closed (yet). I prefer Java over Kotlin.

Repositories

In the language of C, there is my half-finished EPP client (it needs recompiling for every command), my FCM XMPP Connection Server implementation, a half-finished gammu MySQL PDU converter that doesn't connect to MySQL, an LTO encryption tool using SPTI, and my OBS plugin obs-shm-image-source which adds a shared memory image source type to OBS (i.e. displays a Direct3D ID3D11Texture2D stored in the GPU by another program).

In PHP, there is my unmaintained sms_inject repo that used to be able to send SMS messages using gammu with MySQL storage.

I tend to use bash/dash scripts when cobbling things together, such as le-revoke-check-2020 which checked for certificates affected by the Let's Encrypt mass revocation, and my patches to tweet.sh to allow downloading Twitter profile images from a Twitter list of users (rather than writing something that uses the API from scratch). I have many more bash/dash scripts, but they tend to have a specific purpose that wouldn't make sense to post online other than for backup purposes.

I don't really use python, although I have some patches for tplink-smartplug, one of which is based on a gist someone wrote for the new protocol.

C# is my Windows programming language (using C and C++ when I need to such as dabbling with DirectX), although I have used WScript, COM, and bash.exe to call a bash script in WSL2 to avoid writing Windows code. csharp-stream-controller needs fixing and uses WPF and .NET Core, LTO-Encryption-Manager needs finishing, and EditableCMD/EditableCMDSanitised is a console application in .NET 5.0 that may someday be an extensible wrapper around command prompt.

Projects

I have used GitHub repository projects in the past, but by the point I need a GitHub project to organise issues I have likely already got more than one repository the issues relate to. Rather than duplicate the issues in different repositories, they are added to the watfordjc user project that repository is linked to.

My GitHub projects usually get created when issues need prioritising, which typically occurs when the codebase has gotten to the point of needing refactoring and cleaning up.

My Live Streaming Control project covers repositories about live streaming, such as my currently broken OBS stream controller.

My Data Backups and Archiving project is for backing up and archiving data. As well as a Wiki containing thoughts on how I'd achieve that, it includes repositories for LTO tape storage and encryption.

My EditableCMD project is for my command prompt wrapper with editable output and plugin support.

Code Signing

My GitHub commits are normally signed using GPG key 0xBF09A195A052493F80975092380852F8F6CE9235, although there are some instances where I use the GitHub Web interface resulting in GitHub's GPG key 0x5DE3E0509C47EA3CF04A42D34AEE18F83AFDEB23 being used instead.

I do use other GPG keys for commit-signing and code-signing, but these are unlikely to be used on GitHub. Most of my GPG keys are signed by my master signing key, 0xAE04BA84CDC96DD4F2B3D1EB4EEB0C689DE6BB74.

My Debian packages and commits, including those that are Ubuntu-compatible, are signed using GPG key 0xB67D120BDA498C2C66959B031CBF612DBBE5DE6F.

My Ubuntu packages and commits are signed with key 0xA9AE7BD699B94178F4B89F8C8C5E2CC1D6498FBA. My Ubuntu PPAs are signed by Launchpad using key 0x0C7F9AD49DD1D9D38D4387DF9C80A534D162C034.

Commits and packages relating to my infrastructure may be signed by my GPG key for hostmaster (DNS) purposes, 0x9677EA855262A4ECA14D9B21990D7896239C495E.

My Windows builds are signed using my own certificate authority infrastructure.

The root certificate authority is John Cook UK Root CA (.crt), the current intermediate used is John Cook UK Code Signing CA, and my current code-signing certificate is John Cook.

My Android APKs are currently signed using app signing keys that I control. This may change if I start using Play App Signing for an app, such as if I want to use app bundles.

csharp-stream-controller's People

Contributors

watfordjc avatar

Stargazers

 avatar

Watchers

 avatar  avatar

csharp-stream-controller's Issues

Make internationalisation (i18n) possible

Feature Branch

Feature branch has been merged into master.

Progress

  • Convert all strings to resources, with en_GB as native locale.
    • Commit 5467aee:
      • moved StreamController project's NeutralLanguage to AssemblyInfo.cs so resource fallback can be set to MainAssembly to avoid need to create separate en-GB resource file.
      • converted window titles and menu bar item headings to resource strings.
    • Commit 5231ac5 converted control text and accelerator keys to resource strings in WebSocketTest.xaml and SystemTrayIcon.xaml.
    • Commit f1ac4bc converted strings in PreferencesWindow.xaml and validation error strings to resource strings.
    • Commit 1b793af converted colours and strings in NetworkTest.xaml to resource colours and strings.
    • Commit 92a3af4 converted strings in MainWindow.xaml and MainWindow.xaml.cs to resource strings.
    • Commit c1517f9 converted strings in AudioCheck.xaml and AudioCheck.xaml.cs to resource strings.
    • Commit ff97b3a converted strings in WebSocketTest.xaml.cs to resource strings.
    • Commit 4e9022f converted strings in OBSWebSocketLibrary and WebSocketLibrary to resource strings.
  • Commit 804f8f5 added localised resource files for en_US and ensured localisation works.

Background

Related to issue #4 (accessibility) and issue #17 (installer localisation), all strings exposed through the UI should be resources so they can be localised.

This is also a good practice as most GUI strings are constant/static.

LINQ First() should probably be FirstOrDefault()

A lot of the uses of First() have the potential to cause issues. Compare the following two examples, one of which uses First() and the other uses FirstOrDefault():

private void SceneItemRemoved_Event(OBSWebSocketLibrary.Models.Events.SceneItemRemoved messageObject)
{
    OBSWebSocketLibrary.Models.TypeDefs.SceneItem sceneItemToRemove = sceneList.First(x => x.Name == messageObject.SceneName).Sources.First(x => x.Name == messageObject.ItemName);
    sceneList.First(x => x.Name == messageObject.SceneName).Sources.Remove(sceneItemToRemove);
}
private void SourceFilterRemoved_Event(OBSWebSocketLibrary.Models.Events.SourceFilterRemoved messageObject)
{
    OBSWebSocketLibrary.Models.TypeDefs.SourceTypes.BaseType source = (OBSWebSocketLibrary.Models.TypeDefs.SourceTypes.BaseType)obsSourceDictionary[messageObject.SourceName];
    OBSWebSocketLibrary.Models.TypeDefs.FilterTypes.BaseFilter filter = source.Filters.FirstOrDefault(x => x.Name == messageObject.FilterName);
    if (filter != default)
    {
        source.Filters.Remove(filter);
    }
}

By using FirstOrDefault(), default can be compared against to mitigate the potential issue of a list/collection not containing an item that is expected to be there.

Fix memory leaks

Feature Branch

Current feature branch for this issue: not created yet.

Progress

  • Find all the memory leaks and make them disappear.
    • Potential memory leak on disconnect/timer/reconnect.
    • Memory leak on system theme changes.

Background

Memory leaks are bad, especially ones that double the number of objects and heap size.

Find the C#/WPF/CLR equivalent of gdb and work out how to use it. Then use the information to work out the cause.

Application-specific audio channels/devices

Background

OBS audio input and output capture is, given the content of the drop down menus, all about physical audio interfaces. The available devices in OBS directly match my application's system tray default render/capture menus - not only are the lists identical, so is their order.

There are things I'm unfamiliar with in the Windows Audio APIs. Using a virtual audio cable, as well as directing game audio through a 3.5 mm speaker cable that isn't plugged into anything, are essentially workarounds to a problem I don't know how to articulate yet.

There was a time when music technology was my likely academic course choice, and I have dabbled in various audio-related technologies (software/standards/etc.). ALSA, jackd, JACK, Windows USB audio interfaces (as well as issues with unshielded 3.5 mm cables, audio latency, DRM/HDCP) are among the things I have messed with over the years.

The most recent purchase for my laptop is a USB MIDI adaptor, and my ISRC prefix/stem was obtained without joining a royalty collection society. In the land of music recording studios I am UKEQ5, much like in the land of UK domain name registrations I am JOHNCOOK. The corollary is, simply, that although there is software available that can add virtual audio cables/devices/interfaces, I tend to dislike unnecessary middlemen.

Defining the Issue

This issue needs defining with the correct words. At present even the title of the issue is placeholder text.

This is an enhancement issue additionally labelled future (using the first meaning of the future label: "planned for future"). The combination of labels effectively means this issue is about something I want the software to do but don't yet have enough knowledge to know how to start looking at it.

One of the many problems with recording and live streaming is audio. Part of that can be attributed to audio needing to be babysat. This issue is, essentially, all about automating audio stuff following the idea of improved productivity: if you have to do the same thing over and over again, write a script/macro to automate the task.

Let's take a look at a few examples of that task...

  1. To get Subnautica to use my plugged-into-nothing "speaker" output, I have to set that audio device as my default render device before launching the game.
  2. To get my Tweet text-to-speech using a virtual audio cable, I have to workaround a Windows audio preference bug.
  3. To get OBS to use my headphones for audio monitoring, I have to turn on the headphones before starting OBS. If I don't do it in the right order, I have to restart OBS before I can hear the game.
  4. The NVIDIA audio power saving bug can be mitigated by playing silent audio through the device.
  5. The Windows audio preference bug mitigation requires a process play audio before the right audio device(s) are used. It is more difficult playing silent audio through an application than through an audio device because you need to tell the application to play silence and many applications don't have a built-in media player.
  6. OBS has a game capture source and an application window source, but there is no game/application audio source.

There it is: Application-specific audio channels/devices.

Auth required not reported

Feature Branch

Feature branch has been merged into master.

Progress

  • Commit 99251b3:
    • Reversed obs-websocket error text and reported error string order in call to WsClientErrorMessage();
      • Other errors have the more detailed inner exception second. My error string is much more detailed than the obs-websocket error message so should be second too.
    • Modified error handling so that auto-reconnect is disabled if an error is in response to an Authenticate request.
  • Commit 5687a20 changes connection details on changing of connection preferences:
    • Extended ObsWsClient so an instance can be replaced with new connection parameters.
    • Reconnect after changing connection details if auto-reconnect is enabled.
    • Improved some error handling.
  • Commit eee4430 created a connection menu item:
    • Duplicated preference items in menu where suitable, such as auto-reconnect.
    • Added Reconnect and Disconnect items to the menu.

Background

When connecting to obs-websocket that requires authentication, no connection error is reported.

Whilst it is true that a connection is established, the connection is useless.

User action is required to resolve the error, so it should be treated like an HTTP 4xx type error.

The authentication required text should propagate to the UI, and automatic reconnection should be disabled until connection preferences are next saved.

System tray icon unreliable

Feature Branch

Feature branch has been merged into master.

Progress

  • Commit c6178d0:
    • Changed tray icon handling of theme changes.
      • Fixed race condition of new instance also receiving the theme change event causing an infinite loop;
      • Added a 1.5 second delay to showing the system tray icon to mitigate system tray overflow icon moving quickly.
      • Closes context menu before hiding the tray icon - debugging suggests unnecessary as IsOpen == false. Probably only visible because UI hasn't refreshed.
  • Commit 2f5310a shows new instance of tray icon before disposing of old instance of tray icon on theme change.
  • Commit 1f04c9b shows the tray icon when any StyledWindow is closed.
  • Commit ddf1b4a made the application single instance.

Background

The system tray icon sometimes becomes unreliable on system theme changes.

When turning high contrast mode on or off, the tray icon can disappear. If all application windows are closed, there is no way to open a window other than opening the app again. That results in two processes running.

When switching between dark and light modes, the tray icon can enter an infinite hide/restart/show loop if the context menu is open.

Add Tweet Sync Support

Feature Branch

Current feature branch for this issue: feature/issue-36/obs-1.

Progress

OBS Project

  • Migrate any relevant code from the C# library to StreamController.
  • Decide how to tell OBS to switch to a different displayed Tweet.
  • Use existing scripts to fetch a profile image if not already downloaded.
  • Work out how to implement Text to Speech.
    • Add text to speech for currently displayed Tweet.
    • Add ability to change preferred TTS audio output interface.
      • Currently hard-coded to the first render device containing "CABLE" in its FriendlyName falling back to the default render device.
    • Add TTS "limit to" options:
      • Enable TTS for Tweets and Retweets from particular accounts (e.g. @DHSCgovuk).
      • Enable TTS for Tweets matching key phrases (e.g. "critical incident").
    • Add PascalCase and camelCase word splitting.
    • Add initialism (non-pronounceable acronym) character splitting.
  • Fix issue with processing of Tweets stopping working until program restarted.
    • During a stream test it became apparent the Tweets source was no longer being updated and that a restart of Stream Controller was required.
    • Even when it is working, some Tweets cannot be parsed due to COMException.
      • Some try/catch statements are initially pointing at an issue with the verticalMessagePanel.ClearArea() call in DrawVerticalTweet().
      • Potentially fixed by commit e1d1d9d
  • Fix occasional clock delay during Tweet change at the top of the minute. At 60 FPS, saw the minute rollover take 15 frames longer than it should have.
    • Latency/lag issue fixed in commit e6777f9.
  • Fix issue in FileSystemWatcher_Changed() regarding dates and log file rollover.
  • Add a "profileImageAsBadge" boolean option to Tweet image generation. Some profile images have a white circular border nearly touching the edge of the profile picture, presumably for zoom/alignment tweaking when adding to a profile.
    • Work out how to emulate a badge press in Direct2D.
    • Potentially look into how to add depth so it looks more like a real badge.

Twitter API Project

  • Contemplate building Twitter API support into application.

UI Project

  • Create a preferences tab for mIRC log Tweet parsing… IRC Tweet Relay.

Windows Audio Project

  • Fix issue with default render device appearing to be set to default/null (or not updating) on turning off headphones.
    • Add configuration options for TTS output device, TTS monitor device, and whether default audio output should be used if monitor device is not available.

External Repositories

watfordjc/csharp-message-to-image-library

  • Create a Direct2D wrapper library.
    • Create a C++ library that uses Direct2D.
    • Create a way for C# code to interface with the C++ library.
    • Create a C# library.
  • Convert C# library from a WPF application to a library.
  • Convert Direct2D Wrapper Library to a git submodule.
  • Fix memleaks, possibly by using smart pointers.
    • Under investigation.

watfordjc/obs-shm-image-source

  • Look into creating an obs plugin:
    • Look into whether or not there is a way to remove the need to save the Tweet images to files. Can OBS access shared memory?
    • Consider using slideshow instead of image source.
      • Slide show images can be loaded into video memory before they are shown. Changing an image source's file property results in a minuscule delay in switching image while the new image is being loaded.
      • During a stream test it became apparent the lower third slideshow (hard-coded next slide hotkey of F20) wasn't automatically switching slides.
        • The next slide function is currently static void ss_next_slide(void *data) in obs-slideshow.c.
        • Work out if it is possible to call the function from a LUA script (will need to pass a struct slideshow as void *data).
        • Work out if it is possible to make a LUA script function available via obs-websocket.
        • The next version of OBS has media controls. obs-websocket is reporting MediaNext events on slide change and the next version of obs-websocket has a NextMedia request that documentation says currently "Supports only vlc media source (as of OBS v25.0.8)".
  • watfordjc/csharp-message-to-image-library#1 - Use DXGI

Background

With the work done on synchronising clock, weather, and slideshow changes, the only non-synced objects in OBS are the following:

  • Scene changes - I think I want to keep those as they are
  • Tweets - These are currently from a custom mIRC window and are cycled:
    • Every 5 seconds (timer time, not clock time) if there is no text to speech for the Tweet, or,
    • After text to speech has read the Tweet out.
  • Video content (i.e. FaceRig "webcam", game content, etc.) - can't sync without becoming a robot.

My Tweet panel could be changed in a number of ways, and it uses a number of interconnected parts that I haven't published the code for. This issue is going to be a tad complex and require making decisions about whether or not to change my current backend.

Make UI Accessible (a11y)

Feature Branch

Feature branch has been merged into master.

Progress

  • Add accessibility hints to XAML.
    • Commit f0a33e6 labelled several controls in preferences window.
    • Commit c77d3a6 added highlighting of keyboard-focused control in preferences window.
    • Commit dae7c93 styled keyboard focus in other windows and removed tab stop from first level items in menu bar.
      • Commit 0fc4ae2 fixed navigation between first level menu bar entries using arrow keys after pressing Alt.
    • Commit 629c253 added accessible names of controls for some windows, and some more keyboard focus highlighting.
    • Commit e08bee7 modified list item templates so the accessible name matches the displayed text for controls binding to lists of objects, rather than defaulting to the object type.
    • Commit 9c1a77a prefixed the accessible names of scene sources with dependency issues (bold, red) with "Dependency problem for ".
    • Use label controls for labels instead of text blocks, and add access keys to all controls.
      • Commit 4fe9ff2 replaced most TextBlock labels for focusable controls with Label controls, as well as adding access keys for most of those controls.
      • Commit 0867707 rearranged MainWindow group boxes and replaced TextBlock labels with Labels.
    • Add accelerator keys and methods for all buttons.
      • Commit 4fe9ff2 added accelerator keys for some buttons.
      • Commit fc4d515 added method for preferences window save button accelerator key (Ctrl+S) and auto-focus of button if accelerator key used.
      • Commit ce07fa0 added methods and accelerator keys for MainWindow (audio device window).
    • AudioInterfaceCollection and ProcessCollection contain tabular data. Investigate if there is a better way of representing a selected row in MainWindow than using Label and TextBlock. <DataGrid />?
      • Moved: This subject has been moved to issue #26.
    • Commit 3e571a5 reverted some of commit 0867707 turning some Labels in MainWindow back into TextBlocks, and added some UI automation hints.
  • Add accessibility hints to events.
    • Commit 91c01d5:
      • changed the countdown timer text block into a connection status text block: it is now a descriptive version of the connection status icon;
      • made the connection error text block always populated:
        • AOK if there is no error;
        • Error state cleared if there was a connection error but a reconnection attempt is in progress.
    • Commit 98a9a1d added the raising of UI Automation events for validation errors in the preferences window.
    • Commit 0c77879 added:
      • The raising of UI Automation events for connection state changes and the heading of error messages;
      • An F12 shortcut for manually raising a UI Automation event for error state:
        • Extended connection error information if available, or,
        • Connection error state (e.g. a screen reader reading "AOK" if connected).
        • F12 was chosen as it is the Developer Tools keyboard shortcut in most Web browsers and where all the hidden connection information can be accessed.
    • Commit 910b533 added raising of UI Automation events for scene changes and transitions.
      • Difficult to test usability on same machine OBS is running on as OBS also announces events.
    • Commit fc4d515 added validation on preferences window save and raising of a UI Automation event if a save error is displayed.
    • Commit 3e571a5 added UI Automation events for changes to selected audio interface, default render and capture devices, selected application, as well as changes to application's custom render and capture devices.
  • Make fonts and colours accessible:
    • Commit 240bae3 replaced hard-coded fonts and font-sizes with DPI-adjusted font sizes and default system font;
    • Handle OS colour/theme preferences;
      • Commit 37433c9 added some methods (and an Enum) for categorising current user's Windows theme, with High Contrast overriding other possible results.
      • Commit 2d0cac1 fixed a mouse navigation bug when using High Contrast Theme: application crashed after clicking a ComboBox.
      • Have system tray context menu follow user preference for Windows dark/light mode.
        • Commit 0868f15 added a template for ContextMenu that replaces hard-coded colours with ones derived from the menu's foreground colour.
        • Commit f8e5242 create a template for Menu (currently unused) and MenuItem and commit 24ea5b2 made changes to the MenuItem template. Commit 9aade0e moved the colours for Menu and MenuItem, and commit 357ede9 reverted commit 0868f15.
        • Commit fc10dfb introduced a light theme for the system tray context menu.
        • Commit 11afc34 introduced a dark theme for the system tray context menu.
        • Commit 3b874ee created the GetStyledResourceDictionary method so windows can get a collection of ResourceDictionary suitable for the system Windows/App mode that applies to them.
        • Commit 142cf8e had the system tray "window" use GetStyledResourceDictionary on startup and apply the relevant light/dark theme to the system tray icon's context menu.
        • Commit c79e781 restarts the system tray icon when user changes Windows preferences.
      • Commit 8ff6df3 added a high contrast theme and adjusted some styles so they are ignored/different when high contrast is enabled.
      • Commit b6da200 made the Style of StyledWindow exactly the same as that of Window and removed the Template/ControlTemplate. Commit 7647a36 migrated all windows from Window inheritance to StyledWindow inheritance for future styling work.
      • Commit 866837a changed validation warning error colours in Preferences window from hard-coded red to theme-specific colours.
    • Commit 240bae3 replaced hard-coded fonts with system default fonts - there is no font customisation in Windows 10;
    • Choose either a different colour for validation errors or a different colour for keyboard focus.
      • Still undecided on the colour, but commit 629c253 slightly changed the blue colour used for keyboard focus and replaced the solid line with a dashed line.
      • Commit 37433c9 added the method WindowUtilityLibrary.AccentColor, and commit f0b18e1 replaced that with the better named method WindowUtilityLibrary.WindowAccentColor that takes into account there shouldn't be accents in High Contrast mode.
      • Observation: Outside of High Contrast preferences, there doesn't appear to be any way to customise the appearance of keyboard-focused controls. One possibility I could look into is using a user's preferred accent colour as a base colour and creating derived colours from that based on colour contrast. The default blue was my Windows preferences Accent Colour, which (because Settings is in dark mode) is a bit too light in app's Light Mode.
        • New blue doesn't look like much of an issue. To be revisited at another time.
  • Make Preferences window accessible.
    • Commit f0a33e6 modified preference settings window:
      • Modified the window layout;
      • Moved the save box to the bottom so automatic tab indexing doesn't have save as the first thing tabbed to;
      • Added text blocks to display the error text from validation errors.
    • Commit 5865fe0 makes validation real-time, makes validation errors focusable, and validates the URI scheme ComboBox has an item selected.
  • Commit 5de4e94 renamed the Exit window menu option to Close and added the Exit option to exit the application (mirrors tray icon context menu Exit option). It also added access key hints to the Alt+F4 (Close) and Ctrl+Alt+F4 (Exit) keyboard shortcuts, and added handling of Ctrl+Alt+F4.
    • Commit 3d11238 replaced Ctrl+Alt+F4 with Shift+Ctrl+F4 - Ctrl+Alt can replicate AltGr in some keyboard layouts and Shift+Alt+F4 would require intercepting Alt+F4.
  • Commit 1aea007 replaced bindings of whole audio interface devices list with a new active devices list.
    • There is apparently a bug in VirtualizingStackPanel that allows collapsed items to be navigated to using the keyboard.
  • Make custom controls accessible.
    • Make tray icon control accessible.
      • Commit 2337472 modified the list item templates for the tray context menu like e08bee7 did for windows. It also prefixes the accessible name of the default device with "Current default [render/capture] device, ".
      • Moved: Tray icon context menu position issue has been moved to issue #24.
  • Moved: Creating an accessibility options tab/page in the preferences window has been moved to issue #27.

Background

Accessibility. Don't need more background than that.

This needs fixing and continuous reassessment.

Accessibility in Windows 10

Tools

Accessibility Insights for Windows

Accessibility Insights for Windows helps developers find and fix accessibility issues in Windows apps

UIA (User Interface Automation)

Microsoft UI Automation is an accessibility framework that enables Windows applications to provide and consume programmatic information about user interfaces (UIs). It provides programmatic access to most UI elements on the desktop. It enables assistive technology products, such as screen readers, to provide information about the UI to end users and to manipulate the UI by means other than standard input. UI Automation also allows automated test scripts to interact with the UI.

WinAppDriver (Windows Application Driver)

Windows Application Driver (WinAppDriver) is a service to support Selenium-like UI Test Automation on Windows Applications. This service supports testing Universal Windows Platform (UWP), Windows Forms (WinForms), Windows Presentation Foundation (WPF), and Classic Windows (Win32) apps on Windows 10 PCs.

AccEvent (Accessible Event Watcher)

AccEvent is a legacy tool. We recommend using Accessibility Insights instead.

Inspect Tool (UI Inspect)

Inspect is a legacy tool. We recommend using Accessibility Insights instead.

UIA Verify (UI Automation Verify)

UI Automation Verify is a legacy tool. We recommend using Accessibility Insights instead.

Validation error template has hard-coded colour

Feature Branch

Feature branch has been merged into master.

Progress

  • Commit 8b34859 created a custom theme for TextBoxBase and commit a75a2b7 moved the default colours to the light theme colour file.
  • Commit 957db02 added colours for dark theme (currently same as light theme) and high contrast theme.
  • Commit b3f2e38 made the custom TextBoxBase style a named style (i.e. no longer default style for TextBoxBase).
  • Commit 58c1f1d migrated the TextBox controls in the preferences window to the new style.
  • Commit bec2ff0 adjusted colours used in high contrast mode.
  • Commit 23d7e04 added Aero2 style PasswordBox, and commit 7252cdf converted it into named style StyledPasswordBox and added PasswordBoxStyle to themes.
  • Commit 7a1db76 migrated the PasswordBox control in the preferences window to the new style.

Background

Describe the bug
Validation errors place a red box around input controls.

To Reproduce
Steps to reproduce the behavior:

  1. Switch to high contrast mode in Windows settings.
  2. Edit -> Preferences
  3. Enter something invalid.

Expected behavior
In high contrast mode it shouldn't be red.

Screenshots
high-contrast-validation-error

Set system sounds default sound device

The Windows Settings page has System Sounds listed as something you can change the default audio devices for.

This application only lists applications.

Add System Sounds to the application list.

Decide how to deal with tabular name/value pairs

Feature Branch

Feature branch for issue #4 has been merged into master.

Progress

  • AudioInterfaceCollection and ProcessCollection contain tabular data. Investigate if there is a better way of representing a selected row in MainWindow than using Label and TextBlock.
    • After experimenting with DataGrid (commit 540a71f on dead-end branch feature/issue-4/gui-6), among other options, linearly arranged data appears more accessible.
    • Commit 3e571a5 (issue #4) is what I decided to go with for now. If I become aware of a better option, I might reopen this issue.
      • Linear layout with TextBlock name followed by TextBlock value.
      • When a "row" changes, a UI Automation LiveRegionChanged event is raised for the GroupBox containing the name/value pairs for that row.
      • When a value is changed, a UI Automation LiveRegionChanged event is raised for the value TextBlock.
        • There appears to be no way for a UI element to both make visual and logical sense without using a DataGrid, but I deemed that unsuitable.
        • Visually, I want the left side of the values to be vertically aligned. Logically, I want a horizontal StackPanel with a column span of 2 for the two TextBlocks. The StackPanel option would potentially have to break WPF's visual tree, much like a ContextMenu.
        • The value TextBlock therefore also contains its "column name" for its UI Automation Name. It results in the name being duplicated when going through the group box linearly, but it means (for example) when the live region for the default render device of an application has changed, a screen reader gives some context rather than just uttering "Speakers/Headphones".

Background

This issue has been branched from issue #4 (Make UI Accessible (a11y)).

There are several areas in the application where there are drop-down menus for picking an item in a collection of items. This can best be described as picking a row of tabular data which is then selectively displayed in two columns in a grid (so the "column headings" all end at the same position horizontally instead of having different widths.

Unlike the preferences window, the data/information being displayed is read-only, so read-only textboxes are unsuitable. As text blocks are being used, they cannot be labelled.

After a lot of experimentation, I am currently unaware of any better way of arranging name/value pairs than by having a text block label/header followed by a text block value.

Change default sound device

Repository Github Projects

Windows Audio

The latest code for the program has a collection of audio interfaces.

NAudio does not appear to provide a way to change the default devices. A cursory Googling suggests the interface IPolicyConfig10 (plus IPolicyConfigVista and IPolicyConfig7) would need implementing. One such MIT-licensed implementation is frgnca/AudioDeviceCmdlets.

Windows 10 requires too many clicks to change the default render (sound output) device.

  • Create function to change default render device.

NVIDIA DisplayPort Power-Saving Audio Bug

As of a 397.xx/441.xx version of the NVIDIA drivers, my external monitor connected via DisplayPort takes up to a couple of seconds to start outputting audio if the audio output has entered power-saving mode, which is annoying when watching videos. Dell and NVIDIA appear unwilling to fix it, and the Windows device/registry workarounds do not work.

A possible workaround is to constantly play silent audio through the device, which is something this application could implement.

Create branch for obs-websocket version 4.9

Feature Branch

Current feature branch for this issue: feature/issue-8/obs-1.

Progress

  • Commit 60b821c:
    • Added new source types in OBS 26.0.0 RC2.
    • Added new requests in obs-websocket.
    • Added new request replies in obs-websocket.
    • Added new events in obs-websocket.
    • Added new properties in obs-websocket.
  • Add further source types, requests, request replies, events, and properties that are new in the next version of obs-websocket.

The list of changes necessary: obs-websocket Milestone for Version 4.9


Background

Add source types, requests, request replies, events, and properties that are new in the next version of obs-websocket.

CA2227: Collection properties should be read only

Commit fb6057d suppressed many CA2227 FxCop Analyzers warnings because .NET Core 3.1 cannot deserialise JSON to read-only properties. That commit references two issues that are set for .NET Core Runtime System.Text.Json milestone 5.0.0.

Changes to preferences applied prematurely

Progress


Background

Changing settings in preferences result in disconnection/reconnection immediately due to two way binding.

Changes should only be applied after clicking save.

Respond to Windows connectivity issues

The use of TCP means that the software will only become aware of a websocket connection no longer being usable due to a connectivity issue in the following circumstances:

  • An exception is raised in response to an attempt to send a message through a socket or a timeout. IOException being the most likely.
  • An assumption being made after so many seconds of not receiving an obs-websocket Heartbeat event (currently configured at 8 seconds).

The NetworkTest window tests the use of NetworkHelper at responding to connectivity change events.

NetworkConnectivityLevel2 contains the same values as Windows.Networking.Connectivity.NetworkConnectivityLevel, and only exists because I had trouble accessing the Enum in XAML. Those values being:

  • None (no network connection)
  • LocalAccess (network connection, but not Internet connectivity)
  • ConstrainedInternetAccess ("limited" network connection, e.g. having an autoconfiguration IP address)
  • InternetAccess (Internet should be working)

Unlike the NAudio library, where events propagate to sndvol/control panel at virtually the same time as they reach NAudioWrapperLibrary, the WinRT events for connectivity changes take a second or longer to reach NetworkHelper than the events that change the connectivity status icon/text in network settings and the system tray.

As I plan on making this application a "streaming connectivity hub", it should know the state of network connectivity without relying purely on I/O errors. As obs-websocket is currently the only thing being spoken to over the network (well, 127.0.0.1), there isn't much that could currently utilise connectivity state other than another indicator icon. ClientWebSocket does not expose the Ping websocket OpCode, and its default Options.KeepAliveInterval is 30 seconds (read-only after instantiation).

If there is a connectivity issue, ObsWsClient could send a request that has a small reply to test if obs-websocket is still reachable. When connectivity changes to InternetAccess exponential backoff could be reset to the minimum time between reconnections

As well as connectivity level, other things exposed by the API include connection type and whether it is a metered connection.

Reconnections cause additional event listeners

There are two likely causes of this issue:

  1. A new connection is created and the old connection is recreated.
  2. Only one connection exists but the reconnect causes a += for several event listeners.

Set application default sound device

Feature Branch

Feature branch has been merged into master.

Progress

  • Commit da339ed [TODO: Update commit after rebasing/cherry-picking]:
    • Imported and lightly modified some files from the EarTrumpet repository.
  • Attempt to get the device ID of the audio device used by the PID of the Tweets window on my computer using GetPersistedDefaultAudioEndpoint().
    • Commit 9f439ee added method GetDefaultApplicationDevice().
    • Commit e61663b added:
      • a dropdown to MainWindow for picking an application;
      • information about a process including PID and any render/capture device customisations.
  • Attempt to change the audio output device used by the PID of the Tweets window on my computer using SetPersistedDefaultAudioEndpoint().
    • Commit 9f439ee added method ChangeDefaultApplicationDevice().
    • Commit e61663b added:
      • a button to use the selected interface for console audio;
      • a button to clear all application audio interface customisations.
  • Analyse imported code:
    • Additional comments to this issue cover working out what the imported code does.
      • Commit 96ff3e5 added a debug assertion in case IPolicyConfig Guid changes again.
        • IUnknown interface Guid fallback retained for now.
    • Commit c5951bc resolved all warnings given by FxCops Analyzers about the imported code.
  • Create workaround for Windows not consistently following the settings in App volume device preferences:
    • Commit d7f3300 added:
      • a function to toggle a device to the default capture/render device and back to custom again;
      • a button in MainWindow to toggle to default and back to custom for all process IDs with a main window.
    • Commit fe18fc5 added system tray context menu options to :
      • Change default render device (moved to a sub-menu);
      • Change default capture device (new sub-menu);
      • Toggle all audio interface customisations to default device and back again (Ensure Custom Audio option);
      • Exit the application.
    • Commit f0c3773:
      • Added ProcessCollection and ObservableProcess classes;
      • Moved Process.GetProcesses() to ProcessCollection instantiation;
      • Added WMI event watchers to update the ProcessCollection when processes are created and destroyed;
      • Replaced the ItemsSource for the application list in MainWindow with ProcessCollection.Procceses;
      • Added some logic to MainWindow application list combo box.
    • Toggle audio interface customisations (if not default) when a new instance of an application is started.
      • Create a JSON-based user preference file mapping application names to audio devices and audio devices to a list of application names.
        • Commit 1d4f850 added models for JSON objects/POCOs.
        • Commit 1e81d64 added JSON loading and saving.
      • React to process creation.
        • Commit 1700930 added methods to respond to the ProcessCollection changing:
          • Create objects linking application names to audio interfaces;
          • Create objects linking audio interfaces to application names;
          • Change render/capture audio interface for a new process if the currently available data says it shouldn't be the default.
      • Update processName-device and device-processName data when it has:
        • Been changed within this application;
          • Commit d6a7e58 hooked up the methods behind relevant UI interactions (change device for application, reset all application device preferences). It also hooked up device state changes so turning on a headset, for example, will restore the headset as the default device for any applications in the device to application preference list.
        • Been changed within Windows settings.
          • Commit b66a6de added preference conflict detection. Only a debug console message for now - will be split into separate issue.
          • Commit 7c94009 added some further logic:
            • If we think the process should use a custom audio device and Windows thinks it should use the default, we attempt to make Windows change its mind.
            • If that fails, such as due to Windows waiting for the process to make a noise before permitting such a change, the ObservableProcess gets marked as needing its preferred audio devices toggled.
            • If Windows agrees the process should be using a non-default device, the conflict check introduced in commit b66a6de checks for consistency.
            • After the consistency check, the ObservableProcess's AudioDeviceTogglingNeeded property is checked, and if set we toggle the process's audio devices to default and back to custom.
            • All of these checks are performed after the timer fires checking if the JSON needs saving. That fires every 60 seconds, so in theory automatic toggling should occur within 120 seconds of a process making a sound.
            • I believe this commit finally works around the Windows audio bug.
  • Commit ad3a94b made system tray icon application-wide rather than part of the AudioCheck window.

Tray Icon context menu, as described above, default render sub-menu open, PA-279 2- NVIDIA High Definition Audio is checked. Other options in the main menu include exit and ensure custom audio.

Notes

  • Both the EarTrumpet file import and the AudioDeviceCmdlets file import include things I am not familiar with.
    • The file structure is not ideal. Restructuring may make sense once I'm more familiar with what the code does.
    • Changing the folder structure will potentially result in the loss of one or more README/LICENSE files.
      • The MIT LICENSE/LICENSE.md files throughout the repository can potentially be merged. I am not familiar with the merging of the copyright notice lines though.
  • This repository currently forbids merge commits in favour of linear history. If I'm going to start using feature branches, should I change that rule?
  • I currently name feature branches as follows:
    • The first branch is named feature/issue-number/project-shorthand-1
      • For example, this is issue number 18 and the Repository Github Project that is looking at it first is the Windows Audio project (shorthand: audio). That makes the first branch feature/issue-18/audio-1.
    • The branches can become a mess if I'm not careful, which is why I've chosen to create a naming policy.
    • The naming policy prevents the creation of a /feature/issue-18 branch. The inverse is also true, but branches can be renamed through checkout and deletion.
    • If a point is reached where changes going forward might be backtracked, a new branch is created with the last digit increased, e.g. feature/issue-18/audio-2. The same is true if a new branch is created from the master/development branch for starting over or cherry-picking commits.
      • This helps avoid accidental deletion through hard resets and needing to use git reflog to recover a commit.
    • If a different repo project starts working on the issue, such as OBS (shorthand: obs), a new branch is created from one of the existing feature branches. For example, feature/issue-18/audio-2 <- feature/issue-18/obs-1.
      • The idea, currently untested, is to both allow rebasing and cherry-picking.
  • This feature is not currently set to a milestone. Although it might not be too difficult to implement, the fact even Microsoft can't get it working consistently, EarTrumpet have issues with some applications, and my unfamiliarity with what the imported code is actually doing, all have the potential for this issue create a number of related issues.
    • Enough progress has been made that I've added this issue to milestone SC 0.0.4.
  • I think I have worked out the cause of the Windows bug and am thinking about how to implement a workaround.

Windows Bug

  1. You open an application. That application has a process ID. During its life it will have other windows and/or background processes.
  2. You previously told Windows about your App volume device preferences for that application.
  3. The Windows App volume device preferences Settings page displays the MainWindowTitle under the App column.
  4. Windows ignores your volume device preferences for that application until:
    1. The Main Window (latest foreground window for the application) has (I believe) the same or a similar name to that which you set the volume device preferences for that application.
    2. That Main Window makes a sound.
  5. Windows now decides to change the volume device preferences for the main PID of the open application to that which you configured in Settings.
  6. Between step 1 and 5 Windows was using the Default audio devices and settings for your application.
  • In step 5, Windows is essentially doing what it should've already done.
  • Step 4 was confirmed in both StreamController's MainWindow and Windows App volume device preferences Settings window. Render Device and Capture device for mirc-ukem-bot were both set to Default until both prerequisites for step 5 are met.
  • Windows applied the changes in Step 5 to the same PID created in Step 1. Visual Studio output window said A new mirc-ukem-bot.exe process was created with PID 76232! when I clicked the shortcut to that installation of mIRC, and Stream Control MainWindow says mirc-ukem-bot has PID 76232.

Workaround

Using WMI, I am able to track the creation of new processes.

From the events I can extract the Name and ProcessId of newly created PIDs.

From there, I am not sure. My original idea was to fetch the audio preferences for the application through GetPersistedDefaultAudioEndpoint(), but it is now evident that function won't tell me anything other than to assume there isn't any customised audio device settings for the application. It won't tell the truth until Windows is aware of the truth.

The settings are presumably stored in Windows somewhere, but hunting for them in the filesystem and/or registry sounds too labourious.

I think, instead, my program needs its own audio setting data store/database. That will allow the following:

  • On process creation, automatically do to the PID what Windows should be doing.
  • On program startup, enumerate all the running processes and check their names against the list. If an item matches, apply its settings.
  • Have a tray icon context menu option to toggle application audio devices to default and back to custom for those applications with customised audio device settings.
    • As with changing default audio devices, Microsoft require way too many clicks to do this (with a Settings window scroll on top too!)
    • This can probably be done without a data store/database, but it will require thinking about. One option, given what I have experienced, is something like the following:
int pid;
string renderName, captureName
foreach (Process process in Process.GetProcesses()) {
  if (!String.IsNullOrEmpty(process.MainWindowTitle)) {
    pid = process.Id;
    GetPersistedDefaultAudioEndpoint(pid, Render, Console, out renderName);
    if (renderName != AudioInterfaceCollection.Instance.DefaultRender.ID) {
      SetPersistedDefaultAudioEndpoint(pid, Render, Console, AudioInterfaceCollection.Instance.DefaultRender);
      SetPersistedDefaultAudioEndpoint(pid, Render, Console, AudioInterfaceCollection.GetAudioInterfaceById(renderName));
    }
    GetPersistedDefaultAudioEndpoint(pid, Capture, Console, out CaptureName);
    if (renderName != AudioInterfaceCollection.Instance.DefaultCapture.ID) {
      SetPersistedDefaultAudioEndpoint(pid, Capture, Console, AudioInterfaceCollection.Instance.DefaultCapture);
      SetPersistedDefaultAudioEndpoint(pid, Capture, Console, AudioInterfaceCollection.GetAudioInterfaceById(captureName));
    }
  }
}

Background

Somewhat related to issue #10, and also frgnca/AudioDeviceCmdlets#39, is setting the default render/capture device for a specific application.

On my streaming startup list, one of the tasks is setting the audio device for Tweet TTS from virtual audio cable to default and back to virtual audio cable as Windows sometimes ignores the setting.

EarTrumpet (MIT-Licensed) has the following in IAudioPolicyConfigFactory.cs:

...
[Guid("2a59116d-6c4f-45e0-a74f-707e3fef9258")]
...
[PreserveSig]
HRESULT SetPersistedDefaultAudioEndpoint(uint processId, EDataFlow flow, ERole role, IntPtr deviceId);
[PreserveSig]
HRESULT GetPersistedDefaultAudioEndpoint(uint processId, EDataFlow flow, ERole role, [Out, MarshalAs(UnmanagedType.HString)] out string deviceId);
[PreserveSig]
HRESULT ClearAllPersistedApplicationDefaultEndpoints();

A Spanish post on a Microsoft forum also has this code:

...
[Guid("2a59116d-6c4f-45e0-a74f-707e3fef9258")]
...
private void Form1_Load(object sender, EventArgs e)
{

    List<string> DispositivosID = new List<string>();
    List<string> DispositivosName = new List<string>();

    MMDeviceEnum Device = new MMDeviceEnum();
    DispositivosID = Device.GetDevicesID();
    DispositivosName = Device.GetDevicesName();

    comboBox1.Items.AddRange(DispositivosID.ToArray());
    comboBox2.Items.AddRange(DispositivosName.ToArray());

}

private void SetDevice_Click(object sender, EventArgs e)
{

    System.Diagnostics.Process CurrentPro = new System.Diagnostics.Process();

    CurrentPro = System.Diagnostics.Process.GetCurrentProcess();

    int IntPro = Convert.ToInt32(CurrentPro.Id.ToString());

    string deviceId = comboBox1.Text;

    NewPoliceService.SetDefaultEndPoint(deviceId, IntPro);

}

As a pure guess, something like this will set a particular process ID's default sound output device to the current default render device once IAudioPolicyConfigFactory has been imported and I have deciphered how to use it:

SetPersistedDefaultAudioEndpoint(int processID, DataFlow.Render, Role.Console, DefaultRender.ID)

Synchronise OBS slideshow

Feature Branch

Current feature branch for this issue: not created yet.

Progress

  • Create new OBS source items for replacing my current OBS clock/weather HTML source.
    • Background colour source added.
    • Clock text source added.
    • Add weather symbol text source.
    • Add weather temperature text source.
    • Add location text source.
    • Add weather API attribution text source.
  • Update OBS clock time.
  • Fetch weather JSON data.
  • Update OBS weather source text.
  • Cycle through locations every x seconds.
  • Synchronise lower third slideshow with weather location cycling.

Background

In my current OBS scene collection, there are things that happen on screen that are outside of OBS.

The parent timer event

Synchronising on-screen changes will both look more polished as well as being a prerequisite for creating things such as a more graphical "stream starting" countdown timer.

Perhaps the first step will be migrating the clock/weather display from a Web panel to a few OBS native text boxes. A few so they can be independently updated.

That will move the clock from my Web server (with OBS updating the display through JavaScript) to Stream Controller. It will also force a baseline time unit of the Earth minute, assuming I don't want the time to change out of sync with everything else on screen.

So, to start with, I need a clock synchronised with system time (which itself needs to be reasonably accurate) and a timer that, rather than firing every 60 seconds, fires every Earth minute. That itself raises the issue of leap seconds as there are different computer definitions of a minute.

Earth Minute and Leap Seconds

  1. A minute is either 59,000,000,000 nanoseconds, 60,000,000,000 nanoseconds, or 61,000,000,000 nanoseconds.
  2. A minute is always 60,000,000,000 nanoseconds.
  3. Due to clock skewing this minute might be 60,000,004,917 or some other weird non-round number of nanoseconds.

As I currently only care about Windows 10, I need to track down which definition of minute it uses.

Therefore, 2012/7/1 08:59:60 is processed as 2012/7/1 09:00:00, per the ISO 8601 format.
Support for the leap second

First, Microsoft, that isn't ISO 8601 format (prerequisitie link to XKCD on ISO 8601 date format). Secondly, OK, 2012-07-01 08:59:60 is not something Windows does.

During the brief period that follows the introduction of a leap second on an upstream NTP server (including W32time Server), a time difference of about one second occurs between that upstream NTP server and the W32time clients that synchronize from it. The W32time clients correct their local clocks when they subsequently synchronize time from their upstream server.

The system time might change. There might be a WMI event for time synchronisations.

After a brief look at how time synchronisation works in Windows, and the available timers, I don't think I need to worry about how long a second is.

Timers

A DispatchTimer is "reevaluated at the top of every Dispatcher loop. A dispatcher manages a thread's queue. I am thinking I want a dedicated thread for the main timer, set at normal or lower priority. I'm not bothered about accuracy, I'm just after synchronicity.

That timer will fire after every DispatchTimer.Timespan milliseconds. Depending on workload, it might be delayed. However long it is delayed will push the next tick back by at least the duration, introducing some skew as it will never fire before the requested timespan elapses.

After Googling for possible code options, the library Quartz.NET looks like it might be suitable for my needs.

UI thread might be doing too much

In order to prepare for resolving the FxCopAnalyzes code analysis warnings for CA2007: Do not directly await a Task
, commit 5e85852 introduced the following wrapper methods:

  • WebSocket_StateChange_ContextSwitch
  • WebSocket_Error_ContextSwitch
  • WebSocket_Event_ContextSwitch
  • Websocket_Reply_ContextSwitch

These methods take incoming events from the ObsWsClient instance, and have the UI thread call the event handling method that was previously called directly when an event was received.

That change, whilst allowing the use of await Task.ConfigureAwait(false) in the libraries, does mean that some things will now be done unnecessarily on the UI thread.

Some things that need to run on the UI thread in AudioCheck.xaml.cs already do context switching via _Context.Send(), but some things don't. Perhaps the biggest example is DataContext - that is now set via _Context.Send() but not everything that modifies the underlying data would be doing so without the four ContextSwitch wrapper methods.

SourceOrderChanged_Event, for example, might throw an exception as it isn't using _Context.Send() when changing the SortOrder of the current scene's sources.

Commit 5a1c2e1 (CA2012: Use ValueTasks correctly) may be relevant as its diff highlights a lot of method calls that should've previously been awaited.

Connection status icon can blink too fast

Feature Branch

Feature branch has been merged into master.

Progress

  • Commit b6c6ce1 reduced the speed of icon colour changes.
    • Heartbeats give up changing the colour after waiting 250ms for their turn.
    • Connection status changes now show connection status colour for at least one second.

Background

When opening the application, the connection status icon can change colour too quickly.

Colour changes already have a delay built in for obs-websocket heartbeats, but this isn't extended to connection status changes.

Some sort of queuing priority system is needed.

  • A high priority change (i.e. connection status) controls the colour for 1 second. Only one such event can be in the queue.
  • A low priority change (i.e. heartbeats and streaming equivalent) continue to control the colour for 250 milliseconds. Again, only one such event should be in the queue at the time.

Use British English in Installer

I am British. I use British English.

My code might disagree - for reasons spanning back to ~1996 I have tended to use American English for class/property names and British English for variable names. It all goes back to my first HTML page and typing BGCOLOR.

I have tried switching the localisation of the installer to en-gb, but it required a new <WixLocalization /> XML file covering every localisation variable. After I went through all 1,700+ lines in the en-us localisation file and amended the spellings, compilation failed due to ICE31 and ICE17.

  • ICE31: Can't style title bar text of some dialog boxes for some reason (it allegedly can't be styled).
  • ICE17: Missing Icon/Bitmap or something - hard to tell exact error as it is looks like an unescaped single quote ate it. Error is something like"[Icon/Bitmap][space][apostrophe]".

I'm not sure if I'm doing something wrong or if there is a bug in Wix Toolset. Fixing this bug will require some investigative work diving into how Wix Toolset, WixUI, and Windows Installer all work, so for now the installer uses American English.

System tray context menu is in wrong place

Describe the bug
The system tray icon context menu consistently appears in the opposite corner of the screen or the wrong window on first right-click.
Possibly related to Windows (or widespread application) bug with notifications being displayed partially obscured by the system tray and/or partially off the screen.

To Reproduce
Steps to reproduce the behavior:

  1. Right-click the system tray icon
  2. Wonder where the context menu is

Expected behavior
Context menu should appear near the mouse.

Create system tray icon

Repository Github Projects

UI

The latest code for the program has an obs-websocket connection status indicator.

  • Create system tray icon.
  • Use obs-websocket connection status indicator in tray icon.
  • Create a menu for the system tray icon.
  • Bind the tray icon menu to a list of active render devices.
  • Indicate current default render device.

Windows Audio

  • Issue #10.
  • On tray menu item click, change default render device.

Replace restrictive dependency

Feature Branch

All branches for this feature have been abandoned.

Progress

  • Abandon all feature branches containing this issue as the custom control I was using:
    1. Is not accessible;
    2. Would require too much work to make accessible;
    3. Has touch targets that are way too small to be accessible.

Make obs-websocket connection persistent

Feature Branch

Feature branch has been merged into master.

Progress

  • Commit 78eacfd:
    • Refactored AudioCheck.xaml.cs and split out all obs-websocket connection management code to a separate class.
    • Bound AudioCheck connection status controls to new class properties and ensured property change notifications update controls.
    • Bound AudioCheck connection status icon to new class property.
    • Started updating SystemTrayIcon icon from new class.
  • Commit c2a4081:
    • Factored out most of the remaining obs-websocket stuff from AudioCheck into ObsWebsocketConnection.
    • Fixed system tray heart beat icon change when AudioCheck window closed (broken by 78eacfd).
    • Fixed scene data binding when restoring/recreating AudioCheck window (broken by 78eacfd).
  • Commit f07c97a migrated WebSocketTest to ObsWebsocketConnection.
  • Commit cd4dee2 added connection status to system tray icon tool tip (same text displayed next to AudioCheck connection status indicator).
  • Commit 549ce44 factored out the audio workarounds from AudioCheck so they are app-wide.

Background

At the moment, the Audio Check window has a connection and the OBS window has a connection. If the window is closed, the connection is gone.

The connection should be like the tray icon is supposed to be: app-wide. If a connection is already open and the OBS window is opened, it should start showing the raw received data of the existing connection.

The tray icon should, if connected, also show on mouse hover the name of the program and the URI of the obs-websocket server connected to.

There is not currently a plan for multiple established connections from the same instance of the program, although given the way the settings are currently stored and disconnections are handled it would require a second installation of the program in order to connect to different obs-websocket servers.

Issue #30 will require the tray icon implementation be carefully looked at, and given the hidden background process issue it may make sense to turn the application into one that can only have one instance running at a time.

Set application audio device preference back to default

Windows Settings has, among the lists of audio devices you can set as default for an application, the option to change the setting back to default.

Add default to the list of audio devices an application's preferred source can be set to, assuming there is a device ID for "default".

Disable Silent Audio on Idle

Feature Branch

Current feature branch for this issue: not created yet.

Progress

  • Research issue.

Background

Windows does not sleep when audio is playing, even if the audio is silent.

The NVIDIA audio interface sleep bug/slow wake workaround needs to be disabled when the computer is idle, somehow, possibly using WMI and/or events.

Link current scene sources to audio interfaces

The obs-socket response to the GetCurrentScene request includes a sources property which is data type SceneItem[].

SceneItem includes the properties name (string), id (int), type, and groupChildren (SceneItem[] too - recursion).

SceneItem.type might have the value unknown or a source type. An array of source types can be fetched using GetSourceTypesList. Each item in the array has a typeId (SceneItem.type/sourceType), and a type property which is (input | filter | transition | scene).

SceneItem and source mean the same thing, as do SceneItem.type and sourceType.

GetSourceSettings takes a sourceName request parameter (SceneItem.name) and an optional sourceType parameter and the response includes a sourceSettings object that is not well defined.

The NAudio device ID of a source/SceneItem may appear in the sourceSettings object from GetSourceSettings at sourceSettings.device_id. For some source types that could be null, so the NAudio FriendlyName appended with a colon might instead be available at sourceSettings.audio_device_id.

Models.RequestReplies.GetSourceSettings has some sourceSettings properties I have extracted, but it might make more sense to detect the source type given the number of irrelevant properties each source object will have.

Repository Github Projects

OBS

  • GetCurrentScene for early parsed data.
  • GetSourceTypesList to parse the source type data.
  • GetSourcesList so source sourceSettings can use the correct sourceType.
    • Model the properties for each sourceType:
      • scene
      • group
      • audio_line
      • image_source
      • color_source
      • color_source_v2
      • slideshow
      • browser_source
      • ffmpeg_source
      • mask_filter
      • crop_filter
      • gain_filter
      • color_filter
      • scale_filter
      • scroll_filter
      • gpu_delay
      • color_key_filter
      • clut_filter
      • sharpness_filter
      • chroma_key_filter
      • async_delay_filter
      • noise_suppress_filter
      • invert_polarity_filter
      • noise_gate_filter
      • compressor_filter
      • limiter_filter
      • expander_filter
      • luma_key_filter
      • text_gdiplus
      • text_gdiplus_v2
      • cut_transition
      • fade_transition
      • swipe_transition
      • slide_transition
      • obs_stinger_transition
      • fade_to_color_transition
      • wipe_transition
      • vst_filter
      • text_ft2_source
      • text_ft2_source_v2
      • vlc_source
      • monitor_capture
      • window_capture
      • game_capture
      • dshow_input
      • wasapi_input_capture
      • wasapi_output_capture
  • GetSourceSettings to populate the sourceSettings for each source.
  • GetSourceFilters on GetSourcesList to get lists of filters.
    • filters.*.settings = sourceSettings
  • Track changes to sources that are part of current scene and update collection.
    • Scene Items
      • SourceOrderChanged
      • SceneItemAdded
      • SceneItemRemoved
      • SceneItemVisibilityChanged
      • SceneItemLockChanged
      • SceneItemTransformChanged
      • SceneItemSelected
      • SceneItemDeselected
    • Sources
      • SourceCreated
      • SourceDestroyed
      • SourceVolumeChanged
      • SourceMuteStateChanged
      • SourceAudioSyncOffsetChanged
      • SourceAudioMixersChanged
      • SourceRenamed
      • SourceFiltersReordered
      • Source Filters
        • SourceFilterAdded
        • SourceFilterRemoved
        • SourceFilterVisibilityChanged

Windows Audio

  • Create a collection that links OBS sources to physical audio interfaces.
  • Track state changes for underlying audio interfaces and update collection.

UI

  • Change XAML so that current scene's sources can be a collection rather than a string.
  • Bind Windows Audio project's collection to UI element.

Make a portable version

Progress

  • Commit a2ece0b added detection of whether or not running application is installed:
    • If installed, continue using %LOCALAPPDATA% for data and settings.
    • If running from a folder, store data in the same folder.
  • If running from a folder, store settings in the same folder.

Background

Testing of the .zip file version of release 0.0.4 revealed that settings, JSON, etc. are stored in %LOCALAPPDATA% as expected.

The only thing preventing the "Files" version from meeting the definition of portable software is the location of such files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.