Let the device listing match ffmpeg 8's bracket prefix

The dshow parser pinned the bracketed prefix to the `[dshow @ ...]` the
older builds print, and ffmpeg 8 writes `[in#0 @ ...]` there instead: on a
current install every line fell through the anchors, the device list came
back empty, and a dictation with no microphone picked could not start at
all. The prefix is now any bracketed tag, which the anchors and the quoted
name still keep apart from the error lines. Pinned with a listing taken
verbatim from ffmpeg 8.1.2 on Windows 11, third kind marker `(none)`
included.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
huseyin-emre-tigci
2026-08-17 01:02:42 +03:00
co-authored by Claude Fable 5
parent aef33585c1
commit 11a4058e16
2 changed files with 21 additions and 3 deletions
+5 -3
View File
@@ -874,11 +874,13 @@ def _avfoundation_default_output():
# this listing in. Newer builds mark each device `(audio)` or `(video)`; older
# ones print no marker and group the devices under a heading instead. Both are
# anchored at each end, so that the error lines the command ends with, which
# quote the device name that was not found, are not read as devices.
# quote the device name that was not found, are not read as devices. The
# bracketed prefix is not pinned to a spelling: ffmpeg 8 writes `[in#0 @ ...]`
# where the versions before it wrote `[dshow @ ...]`.
_DSHOW_ENTRY = re.compile(
r'^(?:\[dshow @ [^\]]*\]\s*)?"([^"]+)"\s*(?:\(([^)]*)\))?\s*$')
r'^(?:\[[^\]]*\]\s*)?"([^"]+)"\s*(?:\(([^)]*)\))?\s*$')
_DSHOW_ALTERNATIVE = re.compile(
r'^(?:\[dshow @ [^\]]*\]\s*)?Alternative name\s+"([^"]+)"\s*$')
r'^(?:\[[^\]]*\]\s*)?Alternative name\s+"([^"]+)"\s*$')
_DSHOW_HEADING = re.compile(r'DirectShow (audio|video) devices')
# The last listing taken, so that a dictation does not pay for one of its own.
+16
View File
@@ -982,6 +982,22 @@ class WindowsDevices(OnWindows, DikteTest):
with self.listing():
self.assertNotIn("dummy", [name for _, name in audio.list_sources()])
def test_a_listing_from_ffmpeg_8_which_renamed_the_prefix(self):
"""ffmpeg 8 writes `[in#0 @ ...]` where older builds wrote `[dshow @ ...]`."""
listing = (
'[in#0 @ 00000238c3300ac0] "Integrated Camera" (video)\n'
'[in#0 @ 00000238c3300ac0] Alternative name "@device_pnp_\\..."\n'
'[in#0 @ 00000238c3300ac0] "OBS Virtual Camera" (none)\n'
'[in#0 @ 00000238c3300ac0] Alternative name "@device_sw_{860B}"\n'
'[in#0 @ 00000238c3300ac0] "Mikrofon Dizisi (Intel® Smart Sound)" (audio)\n'
'[in#0 @ 00000238c3300ac0] Alternative name "@device_cm_{33D9}"\n'
"Error opening input file dummy.\n"
).encode("utf-8")
with self.listing(stderr=listing):
self.assertEqual(audio.list_sources(),
[("@device_cm_{33D9}",
"Mikrofon Dizisi (Intel® Smart Sound)")])
def test_a_listing_from_an_ffmpeg_that_marks_nothing(self):
"""Older builds print a heading instead of an (audio) on every line."""
listing = (