Skip to content

Commit f511728

Browse files
authored
Fix error in Popen call of ffmpeg (#327)
Make system calls to ffmpeg are more robust Allows sounds extension to work on Linux
1 parent a9e157b commit f511728

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

docs/changelog.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ Master
1616
- Bug fixes
1717
- Make sure double-quotes are properly tokenized for bot commands
1818

19+
20+
- ext.sound
21+
- Bug fixes
22+
- Make system calls to ffmpeg are more robust (works on windows and linux)
23+
1924
- ext.eventsub
2025
- Additions
2126
- Goal subscriptions have been Added
@@ -25,9 +30,11 @@ Master
2530
- :func:`~twitchio.ext.eventsub.event_eventsub_notification_channel_goal_begin`
2631
- :func:`~twitchio.ext.eventsub.event_eventsub_notification_channel_goal_progress`
2732
- :func:`~twitchio.ext.eventsub.event_eventsub_notification_channel_goal_end`
33+
2834
- Bug fixes
2935
Correct typo in :class:`~twitchio.ext.eventsub.HypeTrainBeginProgressData` attribute :attr:`~twitchio.ext.eventsub.HypeTrainBeginProgressData.expires`
3036

37+
3138
2.4.0
3239
======
3340
- TwitchIO
@@ -74,7 +81,7 @@ Master
7481
- Bug fixes
7582
- Add type conversion for variable positional arguments
7683
- Fixed message content while handling commands in reply messages
77-
84+
7885
- ext.pubsub
7986
- Bug fixes
8087
- :class:`~twitchio.ext.pubsub.PubSubModerationAction` now handles missing keys

twitchio/ext/sounds/__init__.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,18 @@
4343

4444
AP = TypeVar("AP", bound="AudioPlayer")
4545

46-
has_ffmpeg: bool
46+
ffmpeg_bin: Optional[str] = None
4747
try:
48-
proc = subprocess.Popen("ffmpeg -version", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
48+
proc = subprocess.Popen(["ffmpeg", "-version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
4949
except FileNotFoundError:
50-
has_ffmpeg = False
50+
try:
51+
proc = subprocess.Popen(["ffmpeg.exe", "-version"])
52+
except FileNotFoundError:
53+
ffmpeg_bin = None
54+
else:
55+
ffmpeg_bin = "ffmpeg.exe"
5156
else:
52-
has_ffmpeg = True
57+
ffmpeg_bin = "ffmpeg"
5358

5459

5560
__all__ = ("Sound", "AudioPlayer")
@@ -127,19 +132,24 @@ class Sound:
127132

128133
YTDL = YoutubeDL(YTDLOPTS)
129134

130-
def __init__(self, source: Optional[Union[str, io.BufferedIOBase]] = None, *, info: Optional[dict] = None):
135+
def __init__(
136+
self,
137+
source: Optional[Union[str, io.BufferedIOBase]] = None,
138+
*,
139+
info: Optional[dict] = None,
140+
):
131141
self.title = None
132142
self.url = None
133143

134144
self.proc = None
135145

136-
if not has_ffmpeg:
137-
raise RuntimeError("ffmpeg is required to create and play Sounds. For more information visit: ...")
146+
if ffmpeg_bin is None:
147+
raise RuntimeError("ffmpeg is required to create and play Sounds. Check your is present in your Path")
138148

139149
if info:
140150
self.proc = subprocess.Popen(
141151
[
142-
"ffmpeg.exe",
152+
ffmpeg_bin,
143153
"-reconnect",
144154
"1",
145155
"-reconnect_streamed",
@@ -165,7 +175,17 @@ def __init__(self, source: Optional[Union[str, io.BufferedIOBase]] = None, *, in
165175
self.title = source
166176

167177
self.proc = subprocess.Popen(
168-
["ffmpeg.exe", "-i", source, "-loglevel", "panic", "-vn", "-f", "s16le", "pipe:1"],
178+
[
179+
ffmpeg_bin,
180+
"-i",
181+
source,
182+
"-loglevel",
183+
"panic",
184+
"-vn",
185+
"-f",
186+
"s16le",
187+
"pipe:1",
188+
],
169189
stdout=subprocess.PIPE,
170190
)
171191

@@ -260,7 +280,9 @@ def _get_devices(self):
260280
continue
261281

262282
self._devices[index] = OutputDevice(
263-
name=device["name"], index=device["index"], channels=device["maxOutputChannels"]
283+
name=device["name"],
284+
index=device["index"],
285+
channels=device["maxOutputChannels"],
264286
)
265287

266288
def play(self, sound: Sound, *, replace: bool = False) -> None:
@@ -284,7 +306,11 @@ def _play_run(self, sound: Sound):
284306

285307
device = self._use_device.index if self._use_device else None
286308
self._stream = self._pa.open(
287-
format=pyaudio.paInt16, output=True, channels=sound.channels, rate=sound.rate, output_device_index=device
309+
format=pyaudio.paInt16,
310+
output=True,
311+
channels=sound.channels,
312+
rate=sound.rate,
313+
output_device_index=device,
288314
)
289315

290316
bytes_ = sound.proc.stdout.read(4096)

0 commit comments

Comments
 (0)