<feed xmlns='http://www.w3.org/2005/Atom'>
<title>meshbay.git/packages/meshbay-node/src/meshbay_node/media_probe.py, branch 0.13</title>
<subtitle>MeshBay — read-only public mirror</subtitle>
<id>https://git.meshbay.org/meshbay.git/atom?h=0.13</id>
<link rel='self' href='https://git.meshbay.org/meshbay.git/atom?h=0.13'/>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/'/>
<updated>2026-09-09T15:16:29Z</updated>
<entry>
<title>fix(node): a video the browser cannot decode is re-encoded, not refused</title>
<updated>2026-09-09T15:16:29Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-09T15:16:29Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=0b9b85bf2d434177968dfc6e27555d54d703ff7e'/>
<id>urn:sha1:0b9b85bf2d434177968dfc6e27555d54d703ff7e</id>
<content type='text'>
Streaming an Xvid/MP3 .avi answered "Unsupported video codec" — a refusal, on
a file ffmpeg re-encodes at about six times playback speed on the machine that
reported it. Nothing about the source was wrong. The node simply never reached
its own re-encode path.

`probe_video` maps a source codec to an MSE codec string and knows four:
h264, hevc, vp9, av1. Everything else returns None, because there is no
MediaSource decoder in any mainstream browser to give a string to — MPEG-4
Part 2 (Xvid, DivX), MPEG-2, VC-1, WMV, Theora. `_stream_video_inner` read
that None as a verdict on the file and refused, while the re-encode sitting
twenty lines below it was gated on `raw_video_codec in
BROWSER_INCOMPATIBLE_VIDEO_CODECS` — a set containing "hevc" and nothing else.
So the whole ffmpeg fallback existed, worked, and was unreachable for every
codec that most needed it.

The setting that governs the fallback has documented the intended behaviour
since it was introduced: draft-v6 §2.11 says `transcode_incompatible_video`
covers "HEVC *and other browser-incompatible video codecs*". Only HEVC was
ever wired up.

Two questions were being answered by one value, and they are separated now.
"Is there a video stream at all" is the only thing this path genuinely cannot
serve, and the only refusal left. "Can it be copied" needs both an MSE string
to put in `stream_init` and a codec browsers decode; a source failing either
is re-encoded.

The operator's opt-out keeps meaning what it says, and it no longer means the
same thing for every source, because it cannot: HEVC has a codec string, so
`transcode_incompatible_video = false` falls back to a copy and the viewer's
own decoder decides (unchanged). MPEG-4 Part 2 has none, so there is nothing
to fall back to — a `stream_init` with no codec string is one the client
refuses before the first byte — and the stream is refused naming the setting.
"Unsupported video codec" is what sent this report to the file, and the file
was fine.

Verified against the reported file end to end: ffprobe reports mpeg4/mp3
720x404, the decision comes out `can_copy=False`, and the pipeline's exact
argv produces H264 High level 4.1 plus stereo AAC-LC — matching the
`avc1.640029,mp4a.40.2` that `stream_init` advertises and that the client puts
through MediaSource.isTypeSupported byte for byte.

test_stream_hevc_transcode.py becomes test_stream_video_transcode.py: it was
always about the policy rather than about one codec, and it now carries both
halves of it, with a synthetic Xvid/MP3 .avi built the same way as the HEVC
clip. Its module-level skip on libx265 went with it — an ffmpeg without x265
still encodes MPEG-4 Part 2, so that marker was skipping the reported defect
entirely on any box without it; it now gates the HEVC cases alone. Three
cases added, checked against the unfixed source. Hub and node suites 2269
passed, 4 skipped.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019GXmScYB1uR29YCt74si9J
</content>
</entry>
<entry>
<title>refactor(node): platform abstraction for Windows portability (W1-W2-W5-W6-W7)</title>
<updated>2026-09-03T14:20:28Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-09-03T14:20:23Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=753653b4df62723b82d32799825135822886eac7'/>
<id>urn:sha1:753653b4df62723b82d32799825135822886eac7</id>
<content type='text'>
Platform directories, signal handling, chmod guards, ffmpeg discovery,
and platform-conditional CLI messages — all testable on Linux.

See docs/WINDOWS-PORT.md §5 for the plan these implement.

Co-Authored-By: Claude Opus 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(node,hub): HEVC transcode fallback, live-add progress, per-group TMDB toggle</title>
<updated>2026-08-24T13:57:41Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-08-24T13:57:41Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=c5585beab3d6adefaa2ef9444946dd3816960a7c'/>
<id>urn:sha1:c5585beab3d6adefaa2ef9444946dd3816960a7c</id>
<content type='text'>
Three bugs found live testing the Videos app against a real HEVC/EAC3 show,
plus a design change requested afterward:

- Streaming always did "-c:v copy", which faithfully reports a source's real
  hev1 codec string but is unplayable in a browser with no HEVC decoder
  (most Chrome/Linux builds). The node now transcodes to H264 whenever the
  probed codec is browser-incompatible (media_probe.py's new
  BROWSER_INCOMPATIBLE_VIDEO_CODECS), with a `transcode_incompatible_video`
  node.toml opt-out for operators who know their viewers already decode it.

- Dropping a whole season into an already-watched folder gave no scanning
  indicator and no progress bar: IndexProgress was only ever updated by the
  two bulk scan paths, never by the real-time per-file watchdog path
  (_schedule_update/_debounce/_update_entry). That path now accounts a
  "burst" the same way, without double-counting a file rewritten mid-debounce.

- A stray literal "0" rendered in the video detail modal when there was no
  TMDB match (`meta.confidence` is 0, and `0 &amp;&amp; x` renders "0" in JSX/htm,
  not nothing) — `confident` is now a real boolean.

- Whether TMDB is used at all moves from a node-wide setting to per-group
  (OP_TMDB_ENABLED/tmdb_enabled/tmdb_enabled_ack, scoped like OP_VIDEO_ROOT):
  an operator running a real media-library group alongside test/demo groups
  on one node wants outbound TMDB traffic for the one that needs it, not all
  of them. The custom API token and query language stay node-wide, one
  shared credential/cache (tmdb_config/OP_TMDB_CONFIG, unchanged reasoning).
  MNP_VERSION 0.6 -&gt; 0.7, additive.

Co-Authored-By: Claude Sonnet 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01LAmyXtc6dAADsH23ydXQpY
</content>
</entry>
<entry>
<title>feat(node,hub): add Videos group app (poster grid, flat list, TMDB metadata)</title>
<updated>2026-08-24T08:04:46Z</updated>
<author>
<name>Christophe Besson</name>
<email>cbesson@gmail.com</email>
</author>
<published>2026-08-24T08:04:46Z</published>
<link rel='alternate' type='text/html' href='https://git.meshbay.org/meshbay.git/commit/?id=6af05abf410bbd038ce7fa6915a659defc509071'/>
<id>urn:sha1:6af05abf410bbd038ce7fa6915a659defc509071</id>
<content type='text'>
Implements docs/mediacenter.md: a "Videos" group application built on the
existing files index rather than a separate catalogue. On the node side,
new indexer enrichment (technical probe, filename/season parsing, thumbnail
generation) runs per-file once an operator has chosen a video_root for the
group, plus a TMDB client for on-demand poster/metadata lookups (never
client-side, thumbnails delivered over the existing chunk path). On the hub
side, a new video-app.js renders a lazily-mounted poster grid or a
thumbnail-only flat list, with TMDB entirely optional per group.

Along the way: the global apps registry now drives Settings' default-tab
picker instead of a hardcoded list, and the video_root is configured from
group Settings (like uploads) rather than from Files, with the node
refusing to run any TMDB/thumbnail work until one is set.

Fixes several bugs found via live testing against a real library, notably
a race between two effects writing the same "image ready" state that could
leave a poster grid spinning forever on a same-tab revisit — see
mediacenter.md §5.4 for the full account of each one.
</content>
</entry>
</feed>
