piwave 2.0.8__py3-none-any.whl → 2.0.9__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 +62 -18
- {piwave-2.0.8.dist-info → piwave-2.0.9.dist-info}/METADATA +1 -1
- piwave-2.0.9.dist-info/RECORD +7 -0
- piwave-2.0.8.dist-info/RECORD +0 -7
- {piwave-2.0.8.dist-info → piwave-2.0.9.dist-info}/WHEEL +0 -0
- {piwave-2.0.8.dist-info → piwave-2.0.9.dist-info}/licenses/LICENSE +0 -0
- {piwave-2.0.8.dist-info → piwave-2.0.9.dist-info}/top_level.txt +0 -0
piwave/piwave.py
CHANGED
|
@@ -120,6 +120,7 @@ class PiWave:
|
|
|
120
120
|
pi: str = "FFFF",
|
|
121
121
|
debug: bool = False,
|
|
122
122
|
silent: bool = False,
|
|
123
|
+
loop: bool = False,
|
|
123
124
|
on_track_change: Optional[Callable] = None,
|
|
124
125
|
on_error: Optional[Callable] = None):
|
|
125
126
|
"""Initialize PiWave FM transmitter.
|
|
@@ -136,6 +137,8 @@ class PiWave:
|
|
|
136
137
|
:type debug: bool
|
|
137
138
|
:param silent: Removes every output log
|
|
138
139
|
:type silent: bool
|
|
140
|
+
:param loop: Loop the current track continuously (default: False)
|
|
141
|
+
:type loop: bool
|
|
139
142
|
:param on_track_change: Callback function called when track changes
|
|
140
143
|
:type on_track_change: Optional[Callable]
|
|
141
144
|
:param on_error: Callback function called when an error occurs
|
|
@@ -152,6 +155,7 @@ class PiWave:
|
|
|
152
155
|
self.ps = str(ps)[:8]
|
|
153
156
|
self.rt = str(rt)[:64]
|
|
154
157
|
self.pi = str(pi).upper()[:4]
|
|
158
|
+
self.loop = loop
|
|
155
159
|
self.on_track_change = on_track_change
|
|
156
160
|
self.on_error = on_error
|
|
157
161
|
|
|
@@ -174,7 +178,7 @@ class PiWave:
|
|
|
174
178
|
atexit.register(self.cleanup)
|
|
175
179
|
|
|
176
180
|
|
|
177
|
-
Log.info(f"PiWave initialized - Frequency: {frequency}MHz, PS: {ps}")
|
|
181
|
+
Log.info(f"PiWave initialized - Frequency: {frequency}MHz, PS: {ps}, Loop: {loop}")
|
|
178
182
|
|
|
179
183
|
def _log_debug(self, message: str):
|
|
180
184
|
if self.debug:
|
|
@@ -331,7 +335,8 @@ class PiWave:
|
|
|
331
335
|
]
|
|
332
336
|
|
|
333
337
|
try:
|
|
334
|
-
|
|
338
|
+
loop_status = "looping" if self.loop else f"Duration: {duration:.1f}s"
|
|
339
|
+
Log.broadcast_message(f"Playing {wav_file} ({loop_status}) at {self.frequency}MHz")
|
|
335
340
|
self.current_process = subprocess.Popen(
|
|
336
341
|
cmd,
|
|
337
342
|
stdout=subprocess.PIPE,
|
|
@@ -342,19 +347,30 @@ class PiWave:
|
|
|
342
347
|
if self.on_track_change:
|
|
343
348
|
self.on_track_change(wav_file)
|
|
344
349
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
350
|
+
if self.loop:
|
|
351
|
+
# if looping is enabled, let pi_fm_rds handle the looping
|
|
352
|
+
# and just wait for stop event
|
|
353
|
+
while not self.stop_event.is_set():
|
|
354
|
+
if self.stop_event.wait(timeout=0.1):
|
|
355
|
+
self._stop_current_process()
|
|
356
|
+
return False
|
|
357
|
+
|
|
358
|
+
# check if process exists cuz why not
|
|
359
|
+
if self.current_process.poll() is not None:
|
|
360
|
+
Log.error("Process ended unexpectedly while looping")
|
|
361
|
+
return False
|
|
362
|
+
else:
|
|
363
|
+
# if not looping wait for stopevent or end of file
|
|
364
|
+
start_time = time.time()
|
|
365
|
+
while True:
|
|
366
|
+
if self.stop_event.wait(timeout=0.1):
|
|
367
|
+
self._stop_current_process()
|
|
368
|
+
return False
|
|
369
|
+
|
|
370
|
+
elapsed = time.time() - start_time
|
|
371
|
+
if elapsed >= duration:
|
|
372
|
+
self._stop_current_process()
|
|
373
|
+
break
|
|
358
374
|
|
|
359
375
|
return True
|
|
360
376
|
|
|
@@ -424,7 +440,8 @@ class PiWave:
|
|
|
424
440
|
|
|
425
441
|
.. note::
|
|
426
442
|
Files are automatically converted to WAV format if needed.
|
|
427
|
-
Only local files are supported.
|
|
443
|
+
Only local files are supported. If loop is enabled, the file will
|
|
444
|
+
repeat continuously until stop() is called.
|
|
428
445
|
|
|
429
446
|
Example:
|
|
430
447
|
>>> pw.play('song.mp3')
|
|
@@ -509,6 +526,7 @@ class PiWave:
|
|
|
509
526
|
pi: Optional[str] = None,
|
|
510
527
|
debug: Optional[bool] = None,
|
|
511
528
|
silent: Optional[bool] = None,
|
|
529
|
+
loop: Optional[bool] = None,
|
|
512
530
|
on_track_change: Optional[Callable] = None,
|
|
513
531
|
on_error: Optional[Callable] = None):
|
|
514
532
|
"""Update PiWave settings.
|
|
@@ -525,6 +543,8 @@ class PiWave:
|
|
|
525
543
|
:type debug: Optional[bool]
|
|
526
544
|
:param silent: Remove every output log
|
|
527
545
|
:type silent: Optional[bool]
|
|
546
|
+
:param loop: Loop the current track continuously
|
|
547
|
+
:type loop: Optional[bool]
|
|
528
548
|
:param on_track_change: Callback function called when track changes
|
|
529
549
|
:type on_track_change: Optional[Callable]
|
|
530
550
|
:param on_error: Callback function called when an error occurs
|
|
@@ -535,7 +555,7 @@ class PiWave:
|
|
|
535
555
|
|
|
536
556
|
Example:
|
|
537
557
|
>>> pw.update(frequency=101.5, ps="NewName")
|
|
538
|
-
>>> pw.update(rt="Updated radio text", debug=True)
|
|
558
|
+
>>> pw.update(rt="Updated radio text", debug=True, loop=True)
|
|
539
559
|
"""
|
|
540
560
|
updated_settings = []
|
|
541
561
|
|
|
@@ -563,6 +583,10 @@ class PiWave:
|
|
|
563
583
|
Log.config(silent=silent)
|
|
564
584
|
updated_settings.append(f"silent: {silent}")
|
|
565
585
|
|
|
586
|
+
if loop is not None:
|
|
587
|
+
self.loop = loop
|
|
588
|
+
updated_settings.append(f"loop: {loop}")
|
|
589
|
+
|
|
566
590
|
if on_track_change is not None:
|
|
567
591
|
self.on_track_change = on_track_change
|
|
568
592
|
updated_settings.append("on_track_change callback updated")
|
|
@@ -591,6 +615,23 @@ class PiWave:
|
|
|
591
615
|
self.frequency = frequency
|
|
592
616
|
Log.broadcast_message(f"Frequency changed to {frequency}MHz. Will update on next file's broadcast.")
|
|
593
617
|
|
|
618
|
+
def set_loop(self, loop: bool):
|
|
619
|
+
"""Enable or disable looping for the current track.
|
|
620
|
+
|
|
621
|
+
:param loop: True to enable looping, False to disable
|
|
622
|
+
:type loop: bool
|
|
623
|
+
|
|
624
|
+
.. note::
|
|
625
|
+
The loop setting will take effect on the next broadcast.
|
|
626
|
+
|
|
627
|
+
Example:
|
|
628
|
+
>>> pw.set_loop(True) # Enable looping
|
|
629
|
+
>>> pw.set_loop(False) # Disable looping
|
|
630
|
+
"""
|
|
631
|
+
self.loop = loop
|
|
632
|
+
loop_status = "enabled" if loop else "disabled"
|
|
633
|
+
Log.broadcast_message(f"Looping {loop_status}. Will update on next file's broadcast.")
|
|
634
|
+
|
|
594
635
|
def get_status(self) -> dict:
|
|
595
636
|
"""Get current status information.
|
|
596
637
|
|
|
@@ -605,11 +646,13 @@ class PiWave:
|
|
|
605
646
|
- **ps** (str): Program Service name
|
|
606
647
|
- **rt** (str): Radio Text message
|
|
607
648
|
- **pi** (str): Program Identification code
|
|
649
|
+
- **loop** (bool): Whether looping is enabled
|
|
608
650
|
|
|
609
651
|
Example:
|
|
610
652
|
>>> status = pw.get_status()
|
|
611
653
|
>>> print(f"Playing: {status['is_playing']}")
|
|
612
654
|
>>> print(f"Current file: {status['current_file']}")
|
|
655
|
+
>>> print(f"Looping: {status['loop']}")
|
|
613
656
|
"""
|
|
614
657
|
return {
|
|
615
658
|
'is_playing': self.is_playing,
|
|
@@ -617,7 +660,8 @@ class PiWave:
|
|
|
617
660
|
'current_file': self.current_file,
|
|
618
661
|
'ps': self.ps,
|
|
619
662
|
'rt': self.rt,
|
|
620
|
-
'pi': self.pi
|
|
663
|
+
'pi': self.pi,
|
|
664
|
+
'loop': self.loop
|
|
621
665
|
}
|
|
622
666
|
|
|
623
667
|
def cleanup(self):
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
piwave/__init__.py,sha256=tAmruZvneieh6fgkf7chKzOX9Q6fEB-5Jt9FJ7Fl5xQ,74
|
|
2
|
+
piwave/piwave.py,sha256=OSSQWrsm37eiyq4GBFkddZnY4qxTfqOmhm05ClIB7w4,24207
|
|
3
|
+
piwave-2.0.9.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
4
|
+
piwave-2.0.9.dist-info/METADATA,sha256=BkYwSKDSJ0eWXxSWZvB3v_YU2HAZJXc3WIgabvyU5yM,11697
|
|
5
|
+
piwave-2.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
piwave-2.0.9.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
|
|
7
|
+
piwave-2.0.9.dist-info/RECORD,,
|
piwave-2.0.8.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
piwave/__init__.py,sha256=tAmruZvneieh6fgkf7chKzOX9Q6fEB-5Jt9FJ7Fl5xQ,74
|
|
2
|
-
piwave/piwave.py,sha256=NG8zDub2qCcy88_zOHL8nD3Jfw9jzlUQyGyXBseLhmI,22249
|
|
3
|
-
piwave-2.0.8.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
|
4
|
-
piwave-2.0.8.dist-info/METADATA,sha256=GJ5BGL6jLHpAiFlSbQQl1OHunLc-jHx0GEudMKs6wao,11697
|
|
5
|
-
piwave-2.0.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
piwave-2.0.8.dist-info/top_level.txt,sha256=xUbZ7Rk6OymSdDxmb9bfO8N-avJ9VYxP41GnXfwKYi8,7
|
|
7
|
-
piwave-2.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|