piwave 2.1.1__py3-none-any.whl → 2.1.3__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/piwave.py CHANGED
@@ -90,7 +90,6 @@ class PiWave:
90
90
  Log.config(silent=silent)
91
91
 
92
92
  self._validate_environment()
93
- atexit.register(self.cleanup)
94
93
 
95
94
  discover_backends()
96
95
 
@@ -326,6 +325,28 @@ class PiWave:
326
325
  self._stop_current_process()
327
326
  return False
328
327
 
328
+ def _playback_worker_wrapper(self):
329
+ # wrapper for non-blocking playback
330
+ try:
331
+ wav_file = self._convert_to_wav(self.current_file)
332
+ if not wav_file:
333
+ Log.error(f"Failed to convert {self.current_file}")
334
+ self.is_playing = False
335
+ return
336
+
337
+ if not os.path.exists(wav_file):
338
+ Log.error(f"File not found: {wav_file}")
339
+ self.is_playing = False
340
+ return
341
+
342
+ self._play_file(wav_file)
343
+ except Exception as e:
344
+ Log.error(f"Playback error: {e}")
345
+ if self.on_error:
346
+ self.on_error(e)
347
+ finally:
348
+ self.is_playing = False
349
+
329
350
 
330
351
  def _play_live(self, audio_source, sample_rate: int, channels: int, chunk_size: int) -> bool:
331
352
  if self.is_playing or self.is_live_streaming:
@@ -443,11 +464,9 @@ class PiWave:
443
464
  def _stop_current_process(self):
444
465
  if self.current_process:
445
466
  try:
446
- Log.info("Stopping current process...")
447
467
  os.killpg(os.getpgid(self.current_process.pid), signal.SIGTERM)
448
468
  self.current_process.wait(timeout=5)
449
469
  except (ProcessLookupError, subprocess.TimeoutExpired):
450
- Log.warning("Forcing kill of current process")
451
470
  try:
452
471
  os.killpg(os.getpgid(self.current_process.pid), signal.SIGKILL)
453
472
  except ProcessLookupError:
@@ -483,18 +502,14 @@ class PiWave:
483
502
  self._log_debug("Playback worker finished")
484
503
 
485
504
 
486
- def _handle_interrupt(self, signum, frame):
487
- Log.warning("Interrupt received, stopping playback...")
488
- self.stop()
489
- os._exit(0)
490
-
491
- def play(self, source, sample_rate: int = 44100, channels: int = 2, chunk_size: int = 4096):
505
+ def play(self, source, sample_rate: int = 44100, channels: int = 2, chunk_size: int = 4096, blocking: bool = False):
492
506
  """Play audio from file or live source.
493
507
 
494
508
  :param source: Either a file path (str) or live audio source (generator/callable/file-like)
495
509
  :param sample_rate: Sample rate for live audio (ignored for files)
496
510
  :param channels: Channels for live audio (ignored for files)
497
511
  :param chunk_size: Chunk size for live audio (ignored for files)
512
+ :param blocking: If the playback should be blocking or not (ignored for live, always non-blocking)
498
513
  :return: True if playback/streaming started successfully
499
514
  :rtype: bool
500
515
 
@@ -506,7 +521,23 @@ class PiWave:
506
521
  # autodetect if source is live or file
507
522
  if isinstance(source, str):
508
523
  # file (string)
509
- return self._play_file(source)
524
+ if blocking:
525
+ return self._play_file(source)
526
+ else:
527
+ if self.is_playing:
528
+ self.stop()
529
+
530
+ self.current_file = source
531
+ self.is_playing = True
532
+ self.stop_event.clear()
533
+
534
+ self.playback_thread = threading.Thread(
535
+ target=self._playback_worker_wrapper,
536
+ daemon=True
537
+ )
538
+ self.playback_thread.start()
539
+ return True
540
+
510
541
  else:
511
542
  # live
512
543
  return self._play_live(source, sample_rate, channels, chunk_size)
@@ -520,7 +551,8 @@ class PiWave:
520
551
  Example:
521
552
  >>> pw.stop()
522
553
  """
523
- if not self.is_playing and not self.is_live_streaming:
554
+
555
+ if not self.is_playing and not self.is_live_streaming and not self.current_process:
524
556
  return
525
557
 
526
558
  Log.warning("Stopping...")
@@ -786,8 +818,6 @@ class PiWave:
786
818
 
787
819
  Log.info("Cleanup completed")
788
820
 
789
- def __del__(self):
790
- self.cleanup()
791
821
 
792
822
  def send(self, file_path: str):
793
823
  """Alias for the play method.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: piwave
3
- Version: 2.1.1
3
+ Version: 2.1.3
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
@@ -518,8 +518,11 @@ status = pw.get_status()
518
518
  ##### `cleanup()`
519
519
  Clean up resources and temporary files.
520
520
 
521
+ > [!WARNING]
522
+ > Always clean up behind you! Dropped support of auto-cleanup on version > 2.1.2
523
+
521
524
  ```python
522
- pw.cleanup() # Called automatically on object destruction
525
+ pw.cleanup()
523
526
  ```
524
527
 
525
528
  ### Backend Management
@@ -1,13 +1,13 @@
1
1
  piwave/__init__.py,sha256=jz2r-qclltKTxJjlGnqhAwIlUgjvRTR31f4hjTHP5NA,230
2
2
  piwave/__main__.py,sha256=ygl6F8VmOZjsnnUbAbzLoA7_1qv18ruG6TW4EocSaQE,3927
3
3
  piwave/logger.py,sha256=lPG3cz3ByqC1p1UKpwlv3R9KgiAb0zzyu6c3bhTpST0,2766
4
- piwave/piwave.py,sha256=p9rsvwx5BdV7bHIW30vj1ipWOrSJOOMjczvs_DtghYA,31335
4
+ piwave/piwave.py,sha256=f3v0n3RBr7sxQ7D1jXunAmplxe0D-6_mdaDLJmGwVpM,32423
5
5
  piwave/backends/__init__.py,sha256=DUbdyYf2V2XcDB05vmFWEkuJ292YTNiNJjzh1raJ5Cg,3756
6
6
  piwave/backends/base.py,sha256=amjdR3pwx-0XN2ngpwfYNt74j5kWrW1cI0zMOTMU-q8,7668
7
7
  piwave/backends/fm_transmitter.py,sha256=6CuYpkCgb40PEpemMlbTkQ6Gq8qFe3C1TSSLLnwXXX4,1338
8
8
  piwave/backends/pi_fm_rds.py,sha256=l1y9JUKjw-d9lh9X7HLQNEwbNVO-whYlzaYnqEfRviI,1429
9
- piwave-2.1.1.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
10
- piwave-2.1.1.dist-info/METADATA,sha256=4nXRHn0KaoiUzo7KegQyG5tEMDx9ZDn4WWBlpzxYa2c,20563
11
- piwave-2.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
- piwave-2.1.1.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
13
- piwave-2.1.1.dist-info/RECORD,,
9
+ piwave-2.1.3.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
10
+ piwave-2.1.3.dist-info/METADATA,sha256=opQ0LdqJda66i1iaOGccjdw0gdZT9b7CKwDC1Ym_xWM,20612
11
+ piwave-2.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
+ piwave-2.1.3.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
13
+ piwave-2.1.3.dist-info/RECORD,,
File without changes