piwave 2.1.5__py3-none-any.whl → 2.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- piwave/backends/base.py +11 -6
- piwave/backends/fm_transmitter.py +2 -2
- piwave/backends/pi_fm_rds.py +1 -1
- piwave/piwave.py +25 -28
- {piwave-2.1.5.dist-info → piwave-2.1.7.dist-info}/METADATA +4 -1
- piwave-2.1.7.dist-info/RECORD +13 -0
- piwave-2.1.5.dist-info/RECORD +0 -13
- {piwave-2.1.5.dist-info → piwave-2.1.7.dist-info}/WHEEL +0 -0
- {piwave-2.1.5.dist-info → piwave-2.1.7.dist-info}/licenses/LICENSE +0 -0
- {piwave-2.1.5.dist-info → piwave-2.1.7.dist-info}/top_level.txt +0 -0
piwave/backends/base.py
CHANGED
|
@@ -231,20 +231,25 @@ class Backend(ABC):
|
|
|
231
231
|
|
|
232
232
|
cmd = self.build_command(wav_file, loop)
|
|
233
233
|
self.current_process = subprocess.Popen(
|
|
234
|
-
cmd,
|
|
235
|
-
|
|
234
|
+
cmd,
|
|
235
|
+
stdout=subprocess.PIPE,
|
|
236
|
+
stderr=subprocess.PIPE,
|
|
237
|
+
preexec_fn=os.setpgrp()
|
|
236
238
|
)
|
|
237
239
|
return self.current_process
|
|
238
240
|
|
|
239
241
|
def stop(self):
|
|
240
242
|
if self.current_process:
|
|
241
243
|
try:
|
|
242
|
-
|
|
244
|
+
self.current_process.terminate()
|
|
243
245
|
self.current_process.wait(timeout=5)
|
|
244
|
-
except
|
|
246
|
+
except subprocess.TimeoutExpired:
|
|
245
247
|
try:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
+
self.current_process.kill()
|
|
249
|
+
self.current_process.wait(timeout=2)
|
|
250
|
+
except:
|
|
248
251
|
pass
|
|
252
|
+
except ProcessLookupError:
|
|
253
|
+
pass
|
|
249
254
|
finally:
|
|
250
255
|
self.current_process = None
|
|
@@ -35,14 +35,14 @@ class FmTransmitterBackend(Backend):
|
|
|
35
35
|
|
|
36
36
|
def build_command(self, wav_file: str, loop: bool):
|
|
37
37
|
return [
|
|
38
|
-
|
|
38
|
+
self.required_executable,
|
|
39
39
|
'-f', str(self.frequency),
|
|
40
40
|
wav_file
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
def build_live_command(self):
|
|
44
44
|
return [
|
|
45
|
-
|
|
45
|
+
self.required_executable,
|
|
46
46
|
'-f', str(self.frequency),
|
|
47
47
|
'-'
|
|
48
48
|
]
|
piwave/backends/pi_fm_rds.py
CHANGED
piwave/piwave.py
CHANGED
|
@@ -298,7 +298,7 @@ class PiWave:
|
|
|
298
298
|
# Only manually loop if the backend does not support it
|
|
299
299
|
while not self.stop_event.is_set():
|
|
300
300
|
if self.stop_event.wait(timeout=0.1):
|
|
301
|
-
self.
|
|
301
|
+
self._stop_curproc()
|
|
302
302
|
return False
|
|
303
303
|
|
|
304
304
|
if self.current_process.poll() is not None:
|
|
@@ -309,7 +309,7 @@ class PiWave:
|
|
|
309
309
|
# fi backend supports looping or we are not looping, just wait for the process to finish
|
|
310
310
|
while not self.stop_event.is_set():
|
|
311
311
|
if self.stop_event.wait(timeout=0.1):
|
|
312
|
-
self.
|
|
312
|
+
self._stop_curproc()
|
|
313
313
|
return False
|
|
314
314
|
if not self.loop and self.current_process.poll() is not None:
|
|
315
315
|
break
|
|
@@ -319,7 +319,7 @@ class PiWave:
|
|
|
319
319
|
Log.error(f"Error playing {wav_file}: {e}")
|
|
320
320
|
if self.on_error:
|
|
321
321
|
self.on_error(e)
|
|
322
|
-
self.
|
|
322
|
+
self._stop_curproc()
|
|
323
323
|
return False
|
|
324
324
|
|
|
325
325
|
|
|
@@ -375,7 +375,7 @@ class PiWave:
|
|
|
375
375
|
stdin=subprocess.PIPE,
|
|
376
376
|
stdout=subprocess.PIPE,
|
|
377
377
|
stderr=subprocess.PIPE,
|
|
378
|
-
preexec_fn=os.
|
|
378
|
+
preexec_fn=os.setpgrp()
|
|
379
379
|
)
|
|
380
380
|
except Exception as e:
|
|
381
381
|
Log.error(f"Failed to start live stream: {e}")
|
|
@@ -458,21 +458,6 @@ class PiWave:
|
|
|
458
458
|
pass
|
|
459
459
|
self.is_live_streaming = False
|
|
460
460
|
|
|
461
|
-
|
|
462
|
-
def _stop_current_process(self):
|
|
463
|
-
if self.current_process:
|
|
464
|
-
try:
|
|
465
|
-
os.killpg(os.getpgid(self.current_process.pid), signal.SIGTERM)
|
|
466
|
-
self.current_process.wait(timeout=5)
|
|
467
|
-
except (ProcessLookupError, subprocess.TimeoutExpired):
|
|
468
|
-
try:
|
|
469
|
-
os.killpg(os.getpgid(self.current_process.pid), signal.SIGKILL)
|
|
470
|
-
except ProcessLookupError:
|
|
471
|
-
pass
|
|
472
|
-
finally:
|
|
473
|
-
self.current_process = None
|
|
474
|
-
|
|
475
|
-
|
|
476
461
|
def _playback_worker(self):
|
|
477
462
|
self._log_debug("Playback worker started")
|
|
478
463
|
|
|
@@ -565,14 +550,7 @@ class PiWave:
|
|
|
565
550
|
except queue.Empty:
|
|
566
551
|
break
|
|
567
552
|
|
|
568
|
-
|
|
569
|
-
try:
|
|
570
|
-
os.killpg(os.getpgid(self.current_process.pid), signal.SIGTERM)
|
|
571
|
-
self.current_process.wait(timeout=5)
|
|
572
|
-
except Exception:
|
|
573
|
-
pass
|
|
574
|
-
finally:
|
|
575
|
-
self.current_process = None
|
|
553
|
+
self._stop_curproc()
|
|
576
554
|
|
|
577
555
|
if self.playback_thread and self.playback_thread.is_alive():
|
|
578
556
|
self.playback_thread.join(timeout=5)
|
|
@@ -583,6 +561,25 @@ class PiWave:
|
|
|
583
561
|
self.is_live_streaming = False
|
|
584
562
|
Log.success("Stopped")
|
|
585
563
|
|
|
564
|
+
def _stop_curproc(self):
|
|
565
|
+
if self.backend.current_process:
|
|
566
|
+
self.backend.stop()
|
|
567
|
+
elif self.current_process:
|
|
568
|
+
# live streaming
|
|
569
|
+
try:
|
|
570
|
+
self.current_process.terminate()
|
|
571
|
+
self.current_process.wait(timeout=5)
|
|
572
|
+
except subprocess.TimeoutExpired:
|
|
573
|
+
try:
|
|
574
|
+
self.current_process.kill()
|
|
575
|
+
self.current_process.wait(timeout=2)
|
|
576
|
+
except:
|
|
577
|
+
pass
|
|
578
|
+
except ProcessLookupError:
|
|
579
|
+
pass
|
|
580
|
+
finally:
|
|
581
|
+
self.current_process = None
|
|
582
|
+
|
|
586
583
|
def pause(self):
|
|
587
584
|
"""Pause the current playback.
|
|
588
585
|
|
|
@@ -593,7 +590,7 @@ class PiWave:
|
|
|
593
590
|
>>> pw.pause()
|
|
594
591
|
"""
|
|
595
592
|
if self.is_playing:
|
|
596
|
-
self.
|
|
593
|
+
self._stop_curproc()
|
|
597
594
|
Log.info("Playback paused")
|
|
598
595
|
|
|
599
596
|
def resume(self):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: piwave
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.7
|
|
4
4
|
Summary: A python module to broadcast radio waves with your Raspberry Pi.
|
|
5
5
|
Home-page: https://github.com/douxxtech/piwave
|
|
6
6
|
Author: Douxx
|
|
@@ -31,6 +31,9 @@ Dynamic: license-file
|
|
|
31
31
|
<h1>PiWave</h1>
|
|
32
32
|
</div>
|
|
33
33
|
|
|
34
|
+
> [!CAUTION]
|
|
35
|
+
> `piwave==2.1.6` is broken ! Please use `piwave==2.1.5`
|
|
36
|
+
|
|
34
37
|
**PiWave** is a Python module designed to manage and control your Raspberry Pi radio using multiple FM transmission backends. It provides a unified interface for broadcasting audio files with multiple backends support and RDS (Radio Data System) support.
|
|
35
38
|
|
|
36
39
|
## Features
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
piwave/__init__.py,sha256=jz2r-qclltKTxJjlGnqhAwIlUgjvRTR31f4hjTHP5NA,230
|
|
2
|
+
piwave/__main__.py,sha256=-Z3RI7TiicE5UwWc4dZaHX82-MpwVXWkfMZXOC457_Q,4089
|
|
3
|
+
piwave/logger.py,sha256=ipWzdNcEYob0xjXP8bbTq9enA3nryU-GKzAOKayRqlg,1149
|
|
4
|
+
piwave/piwave.py,sha256=Pp5z-phr1rHJhmiTFeDYwSYVfNeK3yTsoZp2mtVRo2s,32239
|
|
5
|
+
piwave/backends/__init__.py,sha256=DUbdyYf2V2XcDB05vmFWEkuJ292YTNiNJjzh1raJ5Cg,3756
|
|
6
|
+
piwave/backends/base.py,sha256=NSxSvDkAcbgGcohU9LHVGpn2AdSW3XYM71PAdQXLKds,7811
|
|
7
|
+
piwave/backends/fm_transmitter.py,sha256=Wzsoyi5hqLLZF5eNPmZ7WFvP27OMs2ywJlwrJVut-8w,1403
|
|
8
|
+
piwave/backends/pi_fm_rds.py,sha256=VjcbFeje8LHVr4cBjlL36IcvA3WRfI1hHSGG2ui8Pb0,1467
|
|
9
|
+
piwave-2.1.7.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
10
|
+
piwave-2.1.7.dist-info/METADATA,sha256=BGga7VRHdaH2DBYBiA61Zd_6m-OaP7rD9wpSpF1rFjo,20890
|
|
11
|
+
piwave-2.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
piwave-2.1.7.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
|
|
13
|
+
piwave-2.1.7.dist-info/RECORD,,
|
piwave-2.1.5.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
piwave/__init__.py,sha256=jz2r-qclltKTxJjlGnqhAwIlUgjvRTR31f4hjTHP5NA,230
|
|
2
|
-
piwave/__main__.py,sha256=-Z3RI7TiicE5UwWc4dZaHX82-MpwVXWkfMZXOC457_Q,4089
|
|
3
|
-
piwave/logger.py,sha256=ipWzdNcEYob0xjXP8bbTq9enA3nryU-GKzAOKayRqlg,1149
|
|
4
|
-
piwave/piwave.py,sha256=LdBwjdP_MWC-FSacQYOUUHZUGEVk4wR8K5YmdkgJnzo,32434
|
|
5
|
-
piwave/backends/__init__.py,sha256=DUbdyYf2V2XcDB05vmFWEkuJ292YTNiNJjzh1raJ5Cg,3756
|
|
6
|
-
piwave/backends/base.py,sha256=ttpaxkE-x9l_rQROs3rkrz5qg8kpsIqbmMWyK90Xaf4,7775
|
|
7
|
-
piwave/backends/fm_transmitter.py,sha256=JzO5AswPzuoLOkTPLQrFy8r3trQvxXZrDPIGsrPDtmI,1419
|
|
8
|
-
piwave/backends/pi_fm_rds.py,sha256=GGcOeazzPBV0TF12EESaI_PldZyG_Jowh64cGMuF7R4,1475
|
|
9
|
-
piwave-2.1.5.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
10
|
-
piwave-2.1.5.dist-info/METADATA,sha256=YxawTaGcpPo5hwAqSXJvMbUD_bWW-IvDuHvAhVIdbJM,20819
|
|
11
|
-
piwave-2.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
piwave-2.1.5.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
|
|
13
|
-
piwave-2.1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|