<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marius Vomir</title>
    <description>The latest articles on DEV Community by Marius Vomir (@mariusvomir).</description>
    <link>https://dev.to/mariusvomir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3900808%2F1aaffc95-7343-4b65-aac0-607a44fe883b.png</url>
      <title>DEV Community: Marius Vomir</title>
      <link>https://dev.to/mariusvomir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mariusvomir"/>
    <language>en</language>
    <item>
      <title>Designing Reliable Jellyfin Voice Control with Identity Contracts</title>
      <dc:creator>Marius Vomir</dc:creator>
      <pubDate>Wed, 12 Aug 2026 17:46:19 +0000</pubDate>
      <link>https://dev.to/mariusvomir/designing-reliable-jellyfin-voice-control-with-identity-contracts-656</link>
      <guid>https://dev.to/mariusvomir/designing-reliable-jellyfin-voice-control-with-identity-contracts-656</guid>
      <description>&lt;p&gt;&lt;em&gt;How fixed media slots, explicit destination rules, fail-closed routing, and visible state made voice control easier to reason about.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://voicehomecinema.com/pages/jellyfin-voice-control" rel="noopener noreferrer"&gt;Smart Home Cinema – Voice Control&lt;/a&gt; is a Windows voice-control project designed to control movie playback in an existing Jellyfin setup. While adapting the control layer to Jellyfin, I ran into a design problem that was more important than command transport itself: every accepted phrase had to identify exactly what the system was allowed to act on.&lt;/p&gt;

&lt;p&gt;A short command such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Play Movie Five
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;looks simple because most of its assumptions are hidden.&lt;/p&gt;

&lt;p&gt;Which movie is “Five”? Which television should receive the command? Which Jellyfin user and live session belong to that television? What should happen if the target cannot be resolved safely?&lt;/p&gt;

&lt;p&gt;I ended up treating each accepted voice command as an &lt;strong&gt;identity contract&lt;/strong&gt;. Before execution, the system needs a defined media identity, a defined destination, an allowed action, and a clear failure rule.&lt;/p&gt;

&lt;p&gt;At a high level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;accepted command
    → one media identity
    → one destination identity
    → one allowed action
    → one explicit failure rule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That model became the basis for the rest of the design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Media Identity
&lt;/h2&gt;

&lt;p&gt;A personal Jellyfin library may contain hundreds of films. Open-ended title search sounds natural, but it creates a large interpretation surface.&lt;/p&gt;

&lt;p&gt;Consider:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Play Batman.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A library may contain several Batman films, alternate editions, remakes, collections, or user-specific versions. Speech recognition can add another uncertainty layer.&lt;/p&gt;

&lt;p&gt;A conversational system could rank matches, remember context, ask follow-up questions, and use confidence thresholds. Supporting that behavior requires a different kind of control layer.&lt;/p&gt;

&lt;p&gt;For deterministic playback, I used a dedicated Jellyfin playlist as the controlled media surface. Its first twenty positions became voice-accessible slots:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Position 1  → Play Movie One
Position 2  → Play Movie Two
Position 3  → Play Movie Three
...
Position 20 → Play Movie Twenty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Play Movie Five&lt;/code&gt; points to position five in the configured playlist. The user chooses which films occupy those positions; the control layer preserves the mapping between spoken number and playlist order.&lt;/p&gt;

&lt;p&gt;The rule can be reduced to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numbered voice command
    ↓
requested playlist position
    ↓
item stored at that position
    ↓
valid playable media?
    yes → continue
    no  → reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives the command a stable media identity without searching the entire library.&lt;/p&gt;

&lt;p&gt;The important invariant is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As long as the media assignment for a playlist position remains unchanged, the same numbered command resolves to the same media item.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The vocabulary is deliberately smaller, but every accepted number has a precise meaning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visible State Must Match Media Identity
&lt;/h2&gt;

&lt;p&gt;The television also needs to present the media in the same order used by the command layer.&lt;/p&gt;

&lt;p&gt;The playlist stored by Jellyfin already contains the sequence used by the control layer. Some client views, however, can present the same films in another order, including alphabetical order.&lt;/p&gt;

&lt;p&gt;That creates two different views of the same data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;command engine: playlist order
television UI:  displayed order
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the command layer treats one film as &lt;code&gt;Movie Five&lt;/code&gt; while the fifth visible item on the television is another film, the user has no reliable way to know what the command means.&lt;/p&gt;

&lt;p&gt;The solution was a generated Movie List built from the same playlist sequence used by the command engine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Movie A
2. Movie B
3. Movie C
...
20. Movie T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Movie List is part of the control model. It gives every numbered command a visible reference and lets the user confirm the current assignments directly on the television.&lt;/p&gt;

&lt;p&gt;That produces a second invariant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The order shown to the user must match the order used by the command layer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Visible state and execution state need to describe the same system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Destination Identity
&lt;/h2&gt;

&lt;p&gt;Media identity answers one question: &lt;em&gt;what should be controlled?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The identity contract also needs to define &lt;em&gt;where the command should go&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A Jellyfin environment can contain multiple users, televisions, streaming devices, and active sessions. Selecting a destination by convenience alone can produce accidental success during testing and incorrect routing later.&lt;/p&gt;

&lt;p&gt;One control mode uses an explicitly selected television:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Select TV Two
Play Movie Five
Pause Movie
Forward One Minute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After &lt;code&gt;Select TV Two&lt;/code&gt;, subsequent commands remain associated with that destination until another television is selected.&lt;/p&gt;

&lt;p&gt;This removes several runtime guesses. The system does not need to infer the intended room from microphone proximity, assume that the nearest active screen is correct, or switch targets simply because another client becomes active.&lt;/p&gt;

&lt;p&gt;The selected destination becomes part of the command context.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the Destination Becomes Part of the Command
&lt;/h2&gt;

&lt;p&gt;Independent viewing areas require a stricter routing model.&lt;/p&gt;

&lt;p&gt;Instead of keeping one shared selected target, the destination can be named directly in each command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TV One Play Movie Five
TV Two Pause Movie
TV Three Open Movie List
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each zone has its own configured destination profile and controlled media list. At runtime, the system resolves the eligible Jellyfin target for that profile and rejects the command if the destination is unavailable or ambiguous.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zone named in the command
    ↓
configured destination profile
    ↓
eligible Jellyfin target
    ↓
exactly one valid match?
    yes → continue
    no  → reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The visible zone name is useful to the person speaking. Routing depends on the configured identities behind that name.&lt;/p&gt;

&lt;p&gt;This also means that &lt;code&gt;Movie Five&lt;/code&gt; can legitimately refer to different films in different zones, because each zone can have its own controlled playlist.&lt;/p&gt;

&lt;p&gt;The command remains deterministic because both identities are explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;media identity       = Movie Five
destination identity = TV Two
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Longer commands are a reasonable cost when independent rooms must remain independent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fail Closed When Identity Is Incomplete
&lt;/h2&gt;

&lt;p&gt;Suppose only one television is active during development. A rule such as “use the first available session” may appear reliable.&lt;/p&gt;

&lt;p&gt;The ambiguity becomes visible as soon as another client connects.&lt;/p&gt;

&lt;p&gt;For device control, a guessed destination can be worse than a rejected command. I therefore prefer fail-closed behavior when a required identity is missing or ambiguous:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;missing playlist slot     → reject
unavailable selected TV   → reject
ambiguous client session  → reject
incomplete zone mapping   → reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes configuration problems visible instead of hiding them behind an unrelated session that happened to be available.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Contract Behind Each Command
&lt;/h2&gt;

&lt;p&gt;Once the identities are explicit, the command vocabulary can be described as a set of contracts rather than a list of phrases.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Media identity&lt;/th&gt;
&lt;th&gt;Destination identity&lt;/th&gt;
&lt;th&gt;Failure rule&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Play Movie Five&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Playlist position 5&lt;/td&gt;
&lt;td&gt;Selected television&lt;/td&gt;
&lt;td&gt;Reject if the slot or target is unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Pause Movie&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current media session&lt;/td&gt;
&lt;td&gt;Selected television&lt;/td&gt;
&lt;td&gt;Reject if no eligible session matches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TV Two Play Movie Five&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zone Two playlist position 5&lt;/td&gt;
&lt;td&gt;Zone Two configured destination&lt;/td&gt;
&lt;td&gt;Reject if routing is missing or ambiguous&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TV Three Open Movie List&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zone Three generated list&lt;/td&gt;
&lt;td&gt;Zone Three device&lt;/td&gt;
&lt;td&gt;Reject if the zone target is unavailable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The spoken phrase is the entry point. The contract defines the only meanings the phrase is allowed to have.&lt;/p&gt;

&lt;p&gt;This way of thinking also helps when new commands are added. A command is incomplete until its identity source and failure behavior are defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observable Success Belongs to the Contract Too
&lt;/h2&gt;

&lt;p&gt;A command can be routed correctly and still depend on what the final Jellyfin client supports.&lt;/p&gt;

&lt;p&gt;That matters because server acceptance and user-visible behavior are different layers of the system. The control model therefore treats the client as part of the execution path rather than assuming that a valid request guarantees a visible result.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;command
    + media identity
    + destination identity
    + eligible session
    + client capability
    = intended user-visible action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does not require every Jellyfin client to expose identical capabilities. It requires the control layer to apply only actions that are supported for the target client.&lt;/p&gt;

&lt;p&gt;The same contract idea still applies: support should be based on the behavior the user can actually rely on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cost of Determinism
&lt;/h2&gt;

&lt;p&gt;A deterministic interface gives up some flexibility.&lt;/p&gt;

&lt;p&gt;The trade-offs are visible:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;More flexible approach&lt;/th&gt;
&lt;th&gt;Deterministic approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Search the entire library by title&lt;/td&gt;
&lt;td&gt;Use fixed playlist positions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guess the intended television&lt;/td&gt;
&lt;td&gt;Select or name the destination&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Choose any available session&lt;/td&gt;
&lt;td&gt;Require one exact eligible target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hide incomplete configuration with fallbacks&lt;/td&gt;
&lt;td&gt;Reject commands with unclear identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Let the UI choose its own presentation order&lt;/td&gt;
&lt;td&gt;Show the same order used by the command layer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The deterministic side asks the user to operate inside a smaller, more explicit model.&lt;/p&gt;

&lt;p&gt;In return, the meaning of a valid command is easier to predict before it executes.&lt;/p&gt;

&lt;p&gt;That is especially useful in home automation. The person speaking should not need to know which session the server currently considers active or why one client happened to win an internal selection rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Deliberately Left Outside the Contract
&lt;/h2&gt;

&lt;p&gt;The current control model does not try to solve every voice-interface problem.&lt;/p&gt;

&lt;p&gt;It does not attempt to provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unrestricted full-library title search;&lt;/li&gt;
&lt;li&gt;conversational clarification between similar titles;&lt;/li&gt;
&lt;li&gt;automatic room detection;&lt;/li&gt;
&lt;li&gt;automatic destination selection;&lt;/li&gt;
&lt;li&gt;identical capabilities on every Jellyfin client;&lt;/li&gt;
&lt;li&gt;synchronized playback across several televisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of those features would require additional identity and state rules.&lt;/p&gt;

&lt;p&gt;Full-library search would need ranking, pronunciation handling, confidence thresholds, and clarification. Automatic room detection would need a trustworthy relationship between microphones, users, rooms, and devices. Synchronized playback would introduce timing coordination and drift management.&lt;/p&gt;

&lt;p&gt;Keeping them outside the current model makes the implemented behavior easier to explain and test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Determinism Is a User-Facing Feature
&lt;/h2&gt;

&lt;p&gt;Determinism may sound like an internal implementation detail. The user experiences it directly.&lt;/p&gt;

&lt;p&gt;They experience it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Movie Five&lt;/code&gt; refers to the same position shown on the television;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Pause Movie&lt;/code&gt; reaches the selected target;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TV Two Play Movie Five&lt;/code&gt; cannot affect TV One;&lt;/li&gt;
&lt;li&gt;an unavailable destination produces a clear failure instead of a command somewhere else;&lt;/li&gt;
&lt;li&gt;the interface shows the same state the command engine uses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model can be summarized as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;explicit media identity
+ explicit destination identity
+ allowed action
+ explicit failure behavior
+ observable target behavior
= predictable control
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The broader lesson applies beyond Jellyfin.&lt;/p&gt;

&lt;p&gt;When software controls real devices, every accepted command should have a precise identity contract. The interface becomes easier to trust when the person speaking and the system executing the request share the same definition of what should happen next.&lt;/p&gt;

</description>
      <category>jellyfin</category>
      <category>systemdesign</category>
      <category>architecture</category>
      <category>voicecontrol</category>
    </item>
    <item>
      <title>Building a Voice-Control Layer for Local Movie Playback on Windows</title>
      <dc:creator>Marius Vomir</dc:creator>
      <pubDate>Tue, 28 Apr 2026 19:59:00 +0000</pubDate>
      <link>https://dev.to/mariusvomir/building-a-voice-control-layer-for-local-movie-playback-on-windows-2kam</link>
      <guid>https://dev.to/mariusvomir/building-a-voice-control-layer-for-local-movie-playback-on-windows-2kam</guid>
      <description>&lt;p&gt;For a long time, watching local movies on a Windows PC has been technically easy, but not always comfortable.&lt;/p&gt;

&lt;p&gt;If your PC is connected to a TV or monitor and you are watching from bed, a sofa, or across the room, simple actions can become surprisingly annoying: pause the movie, skip forward, go back, start the next movie, manage subtitles, or shut everything down at the end of the night.&lt;/p&gt;

&lt;p&gt;Most of these actions are easy if you are sitting at the keyboard.&lt;/p&gt;

&lt;p&gt;They are much less convenient when the PC is several meters away.&lt;/p&gt;

&lt;p&gt;That was the starting point for &lt;a href="https://voicehomecinema.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Smart Home Cinema – Voice Control&lt;/strong&gt;&lt;/a&gt;: not to build another media player, and not to build a streaming platform, but to create a local voice-control layer around an existing Windows movie playback workflow.&lt;/p&gt;

&lt;p&gt;The idea was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I wanted to control local movies by voice without turning my PC into a streaming server and without using a phone as a remote.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Update — Local Voice Edition
&lt;/h2&gt;

&lt;p&gt;Since this article was published, Smart Home Cinema has expanded beyond the original Alexa / Google Assistant + TriggerCMD workflow described below.&lt;/p&gt;

&lt;p&gt;The original workflow is now the Voice Assistant Edition. Smart Home Cinema also includes a Local Voice Edition, which uses a microphone connected to the Windows PC and a local voice engine for direct voice control.&lt;/p&gt;

&lt;p&gt;With Local Voice Edition, normal movie playback control does not require Alexa, Google Assistant, TriggerCMD, Google Home, or a smart speaker. After trial or license activation, the local voice-control workflow can run offline for normal playback commands, except for specific online actions such as trial activation, license activation, license rebinding, or optional OpenSubtitles subtitle downloads.&lt;/p&gt;

&lt;p&gt;The article below remains a useful look at the original voice-assistant workflow, the First File Rule, the subtitle workflow, and the local Windows automation model that still powers Smart Home Cinema.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: local playback is still very manual
&lt;/h2&gt;

&lt;p&gt;There are many ways to watch local movie files on Windows.&lt;/p&gt;

&lt;p&gt;You can use VLC Media Player, PotPlayer, or other media players. You can connect the PC to a TV. You can use a wireless mouse, a keyboard, a media remote, or a phone remote app.&lt;/p&gt;

&lt;p&gt;All of these work.&lt;/p&gt;

&lt;p&gt;But they still assume that you are willing to reach for a device, unlock a screen, move a cursor, press keys, or interact manually with the PC.&lt;/p&gt;

&lt;p&gt;For a normal desktop setup, that is fine.&lt;/p&gt;

&lt;p&gt;For a living-room or bedroom setup, it feels unfinished.&lt;/p&gt;

&lt;p&gt;The actual use case is very specific:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the movie files are local;&lt;/li&gt;
&lt;li&gt;the PC is the playback machine;&lt;/li&gt;
&lt;li&gt;the screen may be a TV or monitor;&lt;/li&gt;
&lt;li&gt;the user is away from the keyboard and mouse;&lt;/li&gt;
&lt;li&gt;the desired interaction is voice, not touch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not exactly the same problem solved by a streaming service, a media server, or a generic remote-control app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why generic solutions were not enough
&lt;/h2&gt;

&lt;p&gt;When you look for voice control on Windows, there are many adjacent solutions.&lt;/p&gt;

&lt;p&gt;Some tools provide generic PC voice control. Some apps turn a phone into a remote. Some media-center systems organize or stream media libraries. Some automation tools can trigger commands on a computer.&lt;/p&gt;

&lt;p&gt;Those are useful, but they do not directly solve the full movie-watching workflow.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a phone remote still requires the phone;&lt;/li&gt;
&lt;li&gt;a media server changes the playback model;&lt;/li&gt;
&lt;li&gt;a generic voice tool is not built around movies;&lt;/li&gt;
&lt;li&gt;a tutorial can explain how to connect tools manually, but it is not a finished product;&lt;/li&gt;
&lt;li&gt;a media player plays the file, but does not necessarily provide a full voice-driven session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of Smart Home Cinema was different.&lt;/p&gt;

&lt;p&gt;It was designed as a ready-made Windows app focused specifically on controlling local movie playback by voice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The product category: a local voice-control layer
&lt;/h2&gt;

&lt;p&gt;Smart Home Cinema is best described as a &lt;strong&gt;local Windows voice-control layer for existing local movie playback&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That wording matters.&lt;/p&gt;

&lt;p&gt;VLC Media Player or PotPlayer remains the actual playback engine. Smart Home Cinema does not try to replace them. Instead, it adds a voice-driven workflow around them.&lt;/p&gt;

&lt;p&gt;The core idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;VLC or PotPlayer plays the movie. Smart Home Cinema controls the playback by voice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This makes the product narrower than a media center, but also more focused.&lt;/p&gt;

&lt;p&gt;It does not try to manage every possible media scenario. It focuses on one very specific one: controlling local movie playback on a Windows PC from a distance, using voice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The command chain
&lt;/h2&gt;

&lt;p&gt;Smart Home Cinema now supports two voice-control paths.&lt;/p&gt;

&lt;p&gt;The Local Voice Edition uses a microphone connected to the Windows PC and a local voice engine for direct command recognition.&lt;/p&gt;

&lt;p&gt;The simplified flow is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User voice command
→ microphone connected to the Windows PC
→ local voice engine
→ Smart Home Cinema
→ VLC Media Player or PotPlayer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The Voice Assistant Edition keeps the original assistant-based workflow:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User voice command
→ Alexa or Google Assistant
→ TriggerCMD
→ Windows PC
→ Smart Home Cinema
→ VLC Media Player or PotPlayer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In both cases, Smart Home Cinema executes the local command logic on Windows.&lt;/p&gt;

&lt;p&gt;VLC Media Player or PotPlayer remains the actual media player.&lt;/p&gt;

&lt;p&gt;This separation is important. Smart Home Cinema does not replace VLC or PotPlayer. It adds a focused voice-control layer around them. In the Voice Assistant Edition, Alexa, Google Assistant, and TriggerCMD act as the external command path. In the Local Voice Edition, the command path is handled directly on the Windows PC through a local microphone-based voice engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What made this harder than it sounds
&lt;/h2&gt;

&lt;p&gt;At first glance, voice-controlling a movie player sounds simple.&lt;/p&gt;

&lt;p&gt;You might imagine that every command is just a shortcut:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pause the movie;&lt;/li&gt;
&lt;li&gt;skip forward;&lt;/li&gt;
&lt;li&gt;go back;&lt;/li&gt;
&lt;li&gt;open the next file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But a real viewing workflow is more complicated than that.&lt;/p&gt;

&lt;p&gt;A voice command is not just a keypress. It is an intention.&lt;/p&gt;

&lt;p&gt;When the user says something like “next movie”, the system has to translate that into a predictable local action. Depending on the workflow, that may involve closing the current player session, identifying the next file, moving the watched movie, launching the next one, and restoring the expected viewing state.&lt;/p&gt;

&lt;p&gt;That is where the product becomes more than a list of shortcuts.&lt;/p&gt;

&lt;p&gt;Smart Home Cinema needs to understand the local playback workflow, not just trigger random commands.&lt;/p&gt;

&lt;p&gt;It also has to deal with the fact that VLC and PotPlayer are different applications with different control models. One player may expose a cleaner local interface for some actions. Another may require a different automation strategy. The user should not have to care about those differences while watching a movie.&lt;/p&gt;

&lt;p&gt;The purpose of the app is to hide that complexity behind simple voice commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  The First File Rule
&lt;/h2&gt;

&lt;p&gt;One design choice that helped keep the system predictable is what I call the &lt;strong&gt;First File Rule&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of trying to maintain a complex media database or playlist system, Smart Home Cinema treats the first playable video file in the selected movie folder as the current item.&lt;/p&gt;

&lt;p&gt;That means the folder itself becomes the source of truth.&lt;/p&gt;

&lt;p&gt;This is a simple rule, but it creates a stable workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user controls the first movie in the folder;&lt;/li&gt;
&lt;li&gt;“Next Movie” advances the folder-based queue;&lt;/li&gt;
&lt;li&gt;watched files can be moved out of the active folder;&lt;/li&gt;
&lt;li&gt;the next file becomes the new current item;&lt;/li&gt;
&lt;li&gt;no media library or database is required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach is intentionally minimal.&lt;/p&gt;

&lt;p&gt;It makes the behavior easy to understand, easy to reproduce, and less fragile.&lt;/p&gt;

&lt;p&gt;In most cases, the user does not need to do anything special. Windows already displays files in a folder in a natural order, and Smart Home Cinema simply works with that order. For TV shows, episodes are usually already named sequentially, so episode 1 comes before episode 2, episode 2 comes before episode 3, and so on.&lt;/p&gt;

&lt;p&gt;For standalone movies, the same folder-based order is usually enough. However, if the user wants to watch movies in a specific custom order, they can optionally rename the files with numeric prefixes such as &lt;code&gt;01&lt;/code&gt;, &lt;code&gt;02&lt;/code&gt;, &lt;code&gt;03&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;That is not required for normal use. It is only a simple option for users who want full control over the viewing order.&lt;/p&gt;

&lt;p&gt;For local playback, that kind of predictability matters more than having a complex library system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why local-first matters
&lt;/h2&gt;

&lt;p&gt;A major design decision was to keep playback local.&lt;/p&gt;

&lt;p&gt;The movie files stay on the user’s Windows PC or local storage. Smart Home Cinema does not upload the movie library to a cloud service. It does not stream the movie files from a remote server. It does not turn the product into a content platform. It does not track what the user watches.&lt;/p&gt;

&lt;p&gt;That distinction matters because local movie playback is still a real use case.&lt;/p&gt;

&lt;p&gt;Not every viewing setup is based on streaming platforms. Many users still keep movie files on a PC, external drive, or local folder.&lt;/p&gt;

&lt;p&gt;For those users, the problem is not access to content.&lt;/p&gt;

&lt;p&gt;The problem is convenient control.&lt;/p&gt;

&lt;p&gt;Local Voice Edition strengthens this local-first model. After trial or license activation, normal playback commands can run without an internet connection. Internet is only needed for specific account or licensing actions, such as trial activation, license activation, or license rebinding. Optional online features, such as OpenSubtitles subtitle downloads, require internet only when the user chooses to use them.&lt;/p&gt;

&lt;p&gt;Voice Assistant Edition still uses Alexa or Google Assistant through TriggerCMD as the external command path, but the movie files, media playback, and Smart Home Cinema command logic remain on the user’s Windows PC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why VLC and PotPlayer
&lt;/h2&gt;

&lt;p&gt;VLC Media Player and PotPlayer are widely used Windows media players.&lt;/p&gt;

&lt;p&gt;Smart Home Cinema currently supports them as playback engines because they are already strong at what they do: opening and playing local media files.&lt;/p&gt;

&lt;p&gt;Instead of replacing them, Smart Home Cinema adds a voice-control workflow around them.&lt;/p&gt;

&lt;p&gt;This keeps the responsibilities clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VLC or PotPlayer handles playback;&lt;/li&gt;
&lt;li&gt;Smart Home Cinema handles the local command logic and playback workflow;&lt;/li&gt;
&lt;li&gt;Local Voice Edition handles direct microphone-based voice control on the Windows PC;&lt;/li&gt;
&lt;li&gt;Voice Assistant Edition uses Alexa or Google Assistant through TriggerCMD as the external command path.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That architecture avoids building another media player just to solve a control problem.&lt;/p&gt;

&lt;p&gt;It also keeps the user in a familiar environment. They can continue using the player they already know, while adding a voice-controlled workflow on top.&lt;/p&gt;

&lt;p&gt;The important point is that VLC and PotPlayer remain the media players. Smart Home Cinema is the control layer that makes the local playback setup easier to use from bed, sofa, or across the room.&lt;/p&gt;

&lt;h2&gt;
  
  
  The full viewing workflow
&lt;/h2&gt;

&lt;p&gt;A useful voice-control system needs more than play and pause.&lt;/p&gt;

&lt;p&gt;A real movie session includes many small actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;starting playback;&lt;/li&gt;
&lt;li&gt;pausing and resuming;&lt;/li&gt;
&lt;li&gt;skipping forward or backward;&lt;/li&gt;
&lt;li&gt;moving to the next movie;&lt;/li&gt;
&lt;li&gt;showing progress;&lt;/li&gt;
&lt;li&gt;managing subtitles;&lt;/li&gt;
&lt;li&gt;switching display workflows;&lt;/li&gt;
&lt;li&gt;opening the movie folder;&lt;/li&gt;
&lt;li&gt;stopping playback;&lt;/li&gt;
&lt;li&gt;shutting down the PC at the end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Smart Home Cinema currently includes 25 voice commands organized into movie commands, subtitle commands, and system commands.&lt;/p&gt;

&lt;p&gt;The goal is to support a complete local viewing session without returning to the keyboard or mouse.&lt;/p&gt;

&lt;p&gt;One of the most important commands is “Stop Everything”. In the intended TV-viewing workflow, this can stop playback, move the display workflow back to the PC, and shut down the computer, allowing the user to end the session by voice.&lt;/p&gt;

&lt;p&gt;That is the kind of workflow detail that separates a dedicated product from a generic automation shortcut.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subtitle workflow
&lt;/h2&gt;

&lt;p&gt;Subtitles are another part of the real-world movie experience.&lt;/p&gt;

&lt;p&gt;Searching for subtitles one movie at a time can be slow and repetitive, especially when a folder contains many movies or episodes.&lt;/p&gt;

&lt;p&gt;Smart Home Cinema includes a batch subtitle workflow for local movie folders.&lt;/p&gt;

&lt;p&gt;With a single voice command, the app can search OpenSubtitles and download matching subtitles for multiple local movie or episode files in the selected folder, when matching subtitles are available.&lt;/p&gt;

&lt;p&gt;It also includes subtitle synchronization and cleanup commands, so subtitle handling becomes part of the same local voice-controlled workflow.&lt;/p&gt;

&lt;p&gt;The goal is not just to control playback, but to reduce the manual work around the full movie session.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;To avoid confusion, Smart Home Cinema should not be classified as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a streaming service;&lt;/li&gt;
&lt;li&gt;a media player;&lt;/li&gt;
&lt;li&gt;a cloud media platform;&lt;/li&gt;
&lt;li&gt;a movie provider;&lt;/li&gt;
&lt;li&gt;a media library server;&lt;/li&gt;
&lt;li&gt;a Plex, Kodi, or Jellyfin replacement;&lt;/li&gt;
&lt;li&gt;a smartphone remote app;&lt;/li&gt;
&lt;li&gt;only a DIY automation tutorial.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a narrower product than those categories.&lt;/p&gt;

&lt;p&gt;It focuses on one specific problem: controlling local movie playback on Windows by voice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned from building it
&lt;/h2&gt;

&lt;p&gt;One of the most interesting lessons was that automation is not only about triggering commands.&lt;/p&gt;

&lt;p&gt;Good automation needs context.&lt;/p&gt;

&lt;p&gt;A command like “pause” is simple. But a command like “next movie”, “download subtitles”, or “stop everything” belongs to a larger session. It has to respect the user’s local setup, the current player, the selected folder, the display workflow, and the expected final state.&lt;/p&gt;

&lt;p&gt;Another lesson was that local-first software still has a place.&lt;/p&gt;

&lt;p&gt;A lot of modern entertainment software assumes cloud accounts, streaming platforms, mobile apps, or media servers. Those are useful, but they are not the only model.&lt;/p&gt;

&lt;p&gt;Sometimes the user already has the content, the player, and the screen.&lt;/p&gt;

&lt;p&gt;The missing piece is the control layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Voice control is often discussed in the context of smart homes, speakers, lights, thermostats, or streaming services.&lt;/p&gt;

&lt;p&gt;But local PC workflows still exist.&lt;/p&gt;

&lt;p&gt;A Windows PC connected to a TV is still a common and powerful home entertainment setup. The missing piece is often not playback capability, but comfortable control from a distance.&lt;/p&gt;

&lt;p&gt;Smart Home Cinema was built around that missing layer.&lt;/p&gt;

&lt;p&gt;It is not trying to replace media players or streaming platforms. It is trying to make an existing local movie setup feel more natural, hands-free, and complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;Official website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://voicehomecinema.com/" rel="noopener noreferrer"&gt;https://voicehomecinema.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What Smart Home Cinema is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://voicehomecinema.com/pages/what-is-smart-home-cinema" rel="noopener noreferrer"&gt;https://voicehomecinema.com/pages/what-is-smart-home-cinema&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Public GitHub information page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/voicehomecinema/smart-home-cinema-info" rel="noopener noreferrer"&gt;https://github.com/voicehomecinema/smart-home-cinema-info&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Sometimes a useful software product is not about replacing everything.&lt;/p&gt;

&lt;p&gt;Sometimes it is about connecting existing tools in a way that finally matches how people actually use them.&lt;/p&gt;

&lt;p&gt;For local movie playback on Windows, voice control is that missing layer.&lt;/p&gt;

</description>
      <category>windows</category>
      <category>automation</category>
      <category>productivity</category>
      <category>indiehackers</category>
    </item>
  </channel>
</rss>
