piwave 2.1.6__py3-none-any.whl → 2.1.8__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 CHANGED
@@ -232,20 +232,24 @@ class Backend(ABC):
232
232
  cmd = self.build_command(wav_file, loop)
233
233
  self.current_process = subprocess.Popen(
234
234
  cmd,
235
- stdout=subprocess.PIPE,
236
- stderr=subprocess.PIPE
235
+ stdout=subprocess.DEVNULL,
236
+ stderr=subprocess.DEVNULL,
237
+ stdin=subprocess.DEVNULL
237
238
  )
238
239
  return self.current_process
239
240
 
240
241
  def stop(self):
241
242
  if self.current_process:
242
243
  try:
243
- os.killpg(os.getpgid(self.current_process.pid), signal.SIGTERM)
244
+ self.current_process.terminate()
244
245
  self.current_process.wait(timeout=5)
245
- except (ProcessLookupError, subprocess.TimeoutExpired):
246
+ except subprocess.TimeoutExpired:
246
247
  try:
247
- os.killpg(os.getpgid(self.current_process.pid), signal.SIGKILL)
248
- except ProcessLookupError:
248
+ self.current_process.kill()
249
+ self.current_process.wait(timeout=2)
250
+ except:
249
251
  pass
252
+ except ProcessLookupError:
253
+ pass
250
254
  finally:
251
255
  self.current_process = None
piwave/piwave.py CHANGED
@@ -2,11 +2,10 @@
2
2
  # Licensed under GPLv3.0, main GitHub repository at https://github.com/douxxtech/piwave/
3
3
  # piwave/piwave.py : main entry
4
4
 
5
+ import atexit
5
6
  import os
6
7
  import subprocess
7
- import signal
8
8
  import threading
9
- import time
10
9
 
11
10
  import tempfile
12
11
  import shutil
@@ -88,6 +87,7 @@ class PiWave:
88
87
  Log.config(silent=silent)
89
88
 
90
89
  self._validate_environment()
90
+ atexit.register(self._stop_curproc)
91
91
 
92
92
  discover_backends()
93
93
 
@@ -288,7 +288,8 @@ class PiWave:
288
288
  rds_info = f" (PS: {self.ps})" if self.backend.supports_rds and self.ps else ""
289
289
  Log.broadcast(f"Playing {wav_file} ({loop_status}) at {self.frequency}MHz{rds_info}")
290
290
 
291
- self.current_process = self.backend.play_file(wav_file, self.loop)
291
+ self.backend.play_file(wav_file, self.loop)
292
+ self.current_process = self.backend.current_process
292
293
 
293
294
  if self.on_track_change:
294
295
  self.on_track_change(wav_file)
@@ -298,10 +299,10 @@ class PiWave:
298
299
  # Only manually loop if the backend does not support it
299
300
  while not self.stop_event.is_set():
300
301
  if self.stop_event.wait(timeout=0.1):
301
- self._stop_current_process()
302
+ self._stop_curproc()
302
303
  return False
303
304
 
304
- if self.current_process.poll() is not None:
305
+ if self.backend.current_process.poll() is not None:
305
306
  Log.error("Process ended unexpectedly while looping")
306
307
  return False
307
308
 
@@ -309,9 +310,9 @@ class PiWave:
309
310
  # fi backend supports looping or we are not looping, just wait for the process to finish
310
311
  while not self.stop_event.is_set():
311
312
  if self.stop_event.wait(timeout=0.1):
312
- self._stop_current_process()
313
+ self._stop_curproc()
313
314
  return False
314
- if not self.loop and self.current_process.poll() is not None:
315
+ if not self.loop and self.backend.current_process.poll() is not None:
315
316
  break
316
317
  return True
317
318
 
@@ -319,7 +320,7 @@ class PiWave:
319
320
  Log.error(f"Error playing {wav_file}: {e}")
320
321
  if self.on_error:
321
322
  self.on_error(e)
322
- self._stop_current_process()
323
+ self._stop_curproc()
323
324
  return False
324
325
 
325
326
 
@@ -373,8 +374,8 @@ class PiWave:
373
374
  self.current_process = subprocess.Popen(
374
375
  cmd,
375
376
  stdin=subprocess.PIPE,
376
- stdout=subprocess.PIPE,
377
- stderr=subprocess.PIPE
377
+ stdout=subprocess.DEVNULL,
378
+ stderr=subprocess.DEVNULL
378
379
  )
379
380
  except Exception as e:
380
381
  Log.error(f"Failed to start live stream: {e}")
@@ -457,21 +458,6 @@ class PiWave:
457
458
  pass
458
459
  self.is_live_streaming = False
459
460
 
460
-
461
- def _stop_current_process(self):
462
- if self.current_process:
463
- try:
464
- os.killpg(os.getpgid(self.current_process.pid), signal.SIGTERM)
465
- self.current_process.wait(timeout=5)
466
- except (ProcessLookupError, subprocess.TimeoutExpired):
467
- try:
468
- os.killpg(os.getpgid(self.current_process.pid), signal.SIGKILL)
469
- except ProcessLookupError:
470
- pass
471
- finally:
472
- self.current_process = None
473
-
474
-
475
461
  def _playback_worker(self):
476
462
  self._log_debug("Playback worker started")
477
463
 
@@ -564,14 +550,7 @@ class PiWave:
564
550
  except queue.Empty:
565
551
  break
566
552
 
567
- if self.current_process:
568
- try:
569
- os.killpg(os.getpgid(self.current_process.pid), signal.SIGTERM)
570
- self.current_process.wait(timeout=5)
571
- except Exception:
572
- pass
573
- finally:
574
- self.current_process = None
553
+ self._stop_curproc()
575
554
 
576
555
  if self.playback_thread and self.playback_thread.is_alive():
577
556
  self.playback_thread.join(timeout=5)
@@ -582,6 +561,25 @@ class PiWave:
582
561
  self.is_live_streaming = False
583
562
  Log.success("Stopped")
584
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
+
585
583
  def pause(self):
586
584
  """Pause the current playback.
587
585
 
@@ -592,7 +590,7 @@ class PiWave:
592
590
  >>> pw.pause()
593
591
  """
594
592
  if self.is_playing:
595
- self._stop_current_process()
593
+ self._stop_curproc()
596
594
  Log.info("Playback paused")
597
595
 
598
596
  def resume(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: piwave
3
- Version: 2.1.6
3
+ Version: 2.1.8
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
@@ -1,13 +1,13 @@
1
1
  piwave/__init__.py,sha256=jz2r-qclltKTxJjlGnqhAwIlUgjvRTR31f4hjTHP5NA,230
2
2
  piwave/__main__.py,sha256=-Z3RI7TiicE5UwWc4dZaHX82-MpwVXWkfMZXOC457_Q,4089
3
3
  piwave/logger.py,sha256=ipWzdNcEYob0xjXP8bbTq9enA3nryU-GKzAOKayRqlg,1149
4
- piwave/piwave.py,sha256=8vuShHa3zcKyzt9Yw2942R1QwfKRjleRfElEfw_yFAI,32395
4
+ piwave/piwave.py,sha256=6ns1VmQ8hZFwrI_8HTLwvSD_CwMCzzUWGqms0u1MKeQ,32293
5
5
  piwave/backends/__init__.py,sha256=DUbdyYf2V2XcDB05vmFWEkuJ292YTNiNJjzh1raJ5Cg,3756
6
- piwave/backends/base.py,sha256=D-VbyDNSJUMpZ7PYjCsqEmP5xA3zwWStCm_biZWWAvI,7765
6
+ piwave/backends/base.py,sha256=PJNXEEXZ8wgc343SO5FJ1oGOop--Y-7t01PUWSa5GuE,7818
7
7
  piwave/backends/fm_transmitter.py,sha256=Wzsoyi5hqLLZF5eNPmZ7WFvP27OMs2ywJlwrJVut-8w,1403
8
8
  piwave/backends/pi_fm_rds.py,sha256=VjcbFeje8LHVr4cBjlL36IcvA3WRfI1hHSGG2ui8Pb0,1467
9
- piwave-2.1.6.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
10
- piwave-2.1.6.dist-info/METADATA,sha256=UdEh22ba6NYygU5WRt9G4CG8GcKbRigZevjjwMn5Od8,20819
11
- piwave-2.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
- piwave-2.1.6.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
13
- piwave-2.1.6.dist-info/RECORD,,
9
+ piwave-2.1.8.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
10
+ piwave-2.1.8.dist-info/METADATA,sha256=eO1OgUr8q13UI5TVqcdzokAcUOZnh1WDFGXL5GtJItI,20890
11
+ piwave-2.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
+ piwave-2.1.8.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
13
+ piwave-2.1.8.dist-info/RECORD,,
File without changes