Skip to content

Commit 5a35351

Browse files
committed
- Version 0.8.8-beta6
- Fixing playback for m3u8 on vlc - Fixing "-u" functionality on Windows - Fixing "no player" messages - Stopping runaway threads from displaying messages after the player is stopped
1 parent b2121fe commit 5a35351

File tree

10 files changed

+129
-99
lines changed

10 files changed

+129
-99
lines changed

Changelog

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
1-
2020-11-17
2-
* Versio 0.8.8-beta4
1+
2020-11-23 s-n-g
2+
* Version 0.8.8-beta6
3+
* Fixing playback for m3u8 (vlc)
4+
* Fixing "-u" functionality on Windows
5+
* Fixing "no player" messages
6+
* Stopping runaway threads from displaying messages
7+
after the player is stopped
8+
9+
2020-11-23 s-n-g
10+
* Version 0.8.8-beta5
11+
* Adding VLC support on Windows
12+
13+
2020-11-17 s-n-g
14+
* Version 0.8.8-beta4
315
* Adding the "Force http connections" configuration
416
option (#113)
517
* Fixed a couple of bugs

pyradio/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# New stable version: ''
77
# Beta version: 'betax', x=1,2,3...
88
# RC version: 'RCx', x=1,23...
9-
app_state = 'beta5'
9+
app_state = 'beta6'
1010

1111
__version__ = version = '.'.join(map(str, version_info))
1212
__project__ = __name__

pyradio/browser.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -805,9 +805,7 @@ def get_data_dict(data):
805805
logger.info('Asked to stop after working on "{}"...'.format(an_item))
806806
self._terminated = True
807807
return
808-
# print('I am here')
809808
lock.acquire()
810-
# print('I am here too')
811809
callback(my_data, ret)
812810
lock.release()
813811

pyradio/common.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ def BACKGROUND(): return 1
2222
('Normal Cursor', 6, 0, 0),
2323
('Active Cursor', 9, 0, 0),
2424
('Edit Cursor', 8, 0, 0 ) )
25+
26+
""" Messages to display when player starts / stops
27+
Used in log to stop runaway threads from printing
28+
messages after playback is stopped """
29+
player_start_stop_token = ('Initialization: "', ': Playback stopped')
30+

pyradio/log.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from sys import version_info
44
import logging
55
import threading
6+
from .common import player_start_stop_token
67

78
logger = logging.getLogger(__name__)
89

@@ -22,6 +23,8 @@ class Log(object):
2223

2324
lock = threading.Lock()
2425

26+
_player_stopped = 0
27+
2528
def __init__(self):
2629
self.width = None
2730

@@ -45,9 +48,24 @@ def _do_i_print_last_char(self, first_print):
4548
def write(self, msg=None, suffix=None, counter=None, help_msg=False, error_msg=False, notify_function=None):
4649
if self.cursesScreen:
4750
with self.lock:
51+
if msg:
52+
if player_start_stop_token[1] in msg:
53+
self._player_stopped += 1
54+
elif msg.startswith(player_start_stop_token[0]):
55+
self._player_stopped = 0
56+
if msg and self._player_stopped > 1:
57+
""" Refuse to print anything if "Playback stopped"
58+
was the last message printed
59+
"""
60+
if logger.isEnabledFor(logging.DEBUG):
61+
logger.debug('Refusing to show message; player is stopped: "{}"'.format(msg))
62+
#return
63+
elif self._player_stopped == 1:
64+
self._player_stopped = 2
4865
if self.asked_to_stop:
4966
self.asked_to_stop = False
5067
self.counter = None
68+
self._player_stopped = 0
5169
return
5270
#if logger.isEnabledFor(logging.DEBUG):
5371
# logger.debug('before ----------------------------')
@@ -76,6 +94,7 @@ def write(self, msg=None, suffix=None, counter=None, help_msg=False, error_msg=F
7694
if self.asked_to_stop:
7795
self.asked_to_stop = False
7896
self.counter = None
97+
self._player_stopped = 0
7998
return
8099
""" update main message """
81100
if self.msg:
@@ -101,6 +120,7 @@ def write(self, msg=None, suffix=None, counter=None, help_msg=False, error_msg=F
101120
if self.asked_to_stop:
102121
self.asked_to_stop = False
103122
self.counter = None
123+
self._player_stopped = 0
104124
return
105125
""" display suffix """
106126
if self.suffix:
@@ -153,8 +173,10 @@ def write(self, msg=None, suffix=None, counter=None, help_msg=False, error_msg=F
153173
if self.asked_to_stop:
154174
self.asked_to_stop = False
155175
self.counter = None
176+
self._player_stopped = 0
156177
return
157178
self.cursesScreen.refresh()
179+
#logger.error('DE _player_stopped = {}'.format(self._player_stopped))
158180

159181
def readline(self):
160182
pass

pyradio/main.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ def shell():
141141
sys.exit(1)
142142

143143
if args.use_player != '':
144-
if not platform.startswith('win'):
145-
requested_player = args.use_player
144+
requested_player = args.use_player
146145

147146
if args.list is False and args.add is False:
148147
print('Reading playlist...')
@@ -229,7 +228,6 @@ def print_playlist_selection_error(a_selection, cnf, ret, exit_if_malformed=True
229228
if exit_if_malformed:
230229
if ret == -1:
231230
print('Error: playlist is malformed: "{}"'.format(a_selection))
232-
#print('Error: playlist is malformed: "{}"'.format(args.stations))
233231
sys.exit(1)
234232

235233
if ret == -2:

pyradio/player.py

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,14 @@ def _do_save_volume(self, config_string):
444444
self.PROFILE_FROM_USER = True
445445
return ret_string
446446

447+
def _stop_delay_thread(self):
448+
if self.delay_thread is not None:
449+
try:
450+
self.delay_thread.cancel()
451+
except:
452+
pass
453+
self.delay_thread = None
454+
447455
def _is_in_playback_token(self, a_string):
448456
for a_token in self._playback_token_tuple:
449457
if a_token in a_string:
@@ -511,6 +519,7 @@ def updateStatus(self, *args):
511519
new_input = self.oldUserInput['Title']
512520
self.outputStream.write(msg=new_input, counter='')
513521
self.playback_is_on = True
522+
self._stop_delay_thread()
514523
if 'AO: [' in subsystemOut:
515524
with self.status_update_lock:
516525
if version_info > (3, 0):
@@ -535,14 +544,23 @@ def updateStatus(self, *args):
535544
#logger.error("***** icy_entry")
536545
title = self._format_title_string(subsystemOut)
537546
ok_to_display = False
547+
if not self.playback_is_on:
548+
if logger.isEnabledFor(logging.INFO):
549+
logger.info('*** updateStatus(): Start of playback detected (Icy-Title received) ***')
550+
self.playback_is_on = True
538551
if title[len(self.icy_title_prefix):].strip():
552+
#self._stop_delay_thread()
553+
#logger.error("***** updating title")
539554
self.oldUserInput['Title'] = title
540555
# make sure title will not pop-up while Volume value is on
541556
if self.delay_thread is None:
542557
ok_to_display = True
543558
if ok_to_display and self.playback_is_on:
544559
string_to_show = self.title_prefix + title
545560
self.outputStream.write(msg=string_to_show, counter='')
561+
else:
562+
if logger.isEnabledFor(logging.debug):
563+
logger.debug('***** Title change inhibited: ok_to_display = {0}, playbabk_is_on = {1}'.format(ok_to_display, self.playback_is_on))
546564
else:
547565
ok_to_display = True
548566
if (logger.isEnabledFor(logging.INFO)):
@@ -560,10 +578,14 @@ def updateStatus(self, *args):
560578
else:
561579
for a_token in self.icy_audio_tokens.keys():
562580
if a_token in subsystemOut:
563-
logger.error(' DE token = "{}"'.format(a_token))
564-
logger.error(' DE icy_audio_tokens[a_token] = "{}"'.format(self.icy_audio_tokens[a_token]))
581+
if not self.playback_is_on:
582+
if logger.isEnabledFor(logging.INFO):
583+
logger.info('*** updateStatus(): Start of playback detected (Icy audio token received) ***')
584+
self.playback_is_on = True
585+
#logger.error(' DE token = "{}"'.format(a_token))
586+
#logger.error(' DE icy_audio_tokens[a_token] = "{}"'.format(self.icy_audio_tokens[a_token]))
565587
a_str = subsystemOut.split(a_token)
566-
logger.error(' DE str = "{}"'.format(a_str))
588+
#logger.error(' DE str = "{}"'.format(a_str))
567589
with self.status_update_lock:
568590
if self.icy_audio_tokens[a_token] == 'icy-br':
569591
self._icy_data[self.icy_audio_tokens[a_token]] = a_str[1].replace('kbit/s', '')
@@ -742,7 +764,7 @@ def updateWinVLCStatus(self, *args):
742764
except:
743765
pass
744766
if (not self.playback_is_on) and (logger.isEnabledFor(logging.INFO)):
745-
logger.info('*** updateStatus(): Start of playback detected ***')
767+
logger.info('*** updateWinVLCStatus(): Start of playback detected ***')
746768
#if self.outputStream.last_written_string.startswith('Connecting to'):
747769
if self.oldUserInput['Title'] == '':
748770
new_input = 'Playing: "{}"'.format(self.name)
@@ -761,6 +783,10 @@ def updateWinVLCStatus(self, *args):
761783
elif self._is_icy_entry(subsystemOut):
762784
if stop():
763785
break
786+
if not self.playback_is_on:
787+
if logger.isEnabledFor(logging.INFO):
788+
logger.info('*** updateWinVLCStatus(): Start of playback detected (Icy-Title received) ***')
789+
self.playback_is_on = True
764790

765791
#logger.error("***** icy_entry")
766792
title = self._format_title_string(subsystemOut)
@@ -792,10 +818,14 @@ def updateWinVLCStatus(self, *args):
792818
break
793819
for a_token in self.icy_audio_tokens.keys():
794820
if a_token in subsystemOut:
795-
logger.error(' DE token = "{}"'.format(a_token))
796-
logger.error(' DE icy_audio_tokens[a_token] = "{}"'.format(self.icy_audio_tokens[a_token]))
821+
if not self.playback_is_on:
822+
if logger.isEnabledFor(logging.INFO):
823+
logger.info('*** updateWinVLCStatus(): Start of playback detected (Icy audio token received) ***')
824+
self.playback_is_on = True
825+
#logger.error(' DE token = "{}"'.format(a_token))
826+
#logger.error(' DE icy_audio_tokens[a_token] = "{}"'.format(self.icy_audio_tokens[a_token]))
797827
a_str = subsystemOut.split(a_token)
798-
logger.error(' DE str = "{}"'.format(a_str))
828+
#logger.error(' DE str = "{}"'.format(a_str))
799829
with self.status_update_lock:
800830
if self.icy_audio_tokens[a_token] == 'icy-br':
801831
self._icy_data[self.icy_audio_tokens[a_token]] = a_str[1].replace('kbit/s', '')
@@ -988,23 +1018,24 @@ def _set_mpv_playback_is_on(self, stop):
9881018

9891019
def threadUpdateTitle(self, delay=1):
9901020
if self.oldUserInput['Title'] != '':
991-
try:
992-
self.delay_thread.cancel()
993-
except:
994-
pass
1021+
self._stop_delay_thread()
9951022
try:
9961023
self.delay_thread = threading.Timer(delay,
9971024
self.updateTitle,
9981025
[ self.outputStream,
999-
self.title_prefix + self._format_title_string(self.oldUserInput['Title']) ]
1026+
None ]
10001027
)
10011028
self.delay_thread.start()
10021029
except:
10031030
if (logger.isEnabledFor(logging.DEBUG)):
10041031
logger.debug("delay thread start failed")
10051032

10061033
def updateTitle(self, *arg, **karg):
1007-
arg[0].write(msg=arg[1])
1034+
self._stop_delay_thread()
1035+
if arg[1]:
1036+
arg[0].write(msg=arg[1])
1037+
else:
1038+
arg[0].write(msg=self.title_prefix + self._format_title_string(self.oldUserInput['Title']))
10081039

10091040
def _is_icy_entry(self, a_string):
10101041
#logger.error("**** a_string = {}".format(a_string))
@@ -1044,6 +1075,7 @@ def play(self, name, streamUrl, encoding = ''):
10441075
self.show_volume = True
10451076
self.title_prefix = ''
10461077
self.playback_is_on = False
1078+
self.delay_thread = None
10471079
self.outputStream.write(msg='Station: "{}" - Opening connection...'.format(name), counter='')
10481080
if logger.isEnabledFor(logging.INFO):
10491081
logger.info('Selected Station: "{}"'.format(name))
@@ -1130,11 +1162,7 @@ def close(self):
11301162
self.connection_timeout_thread.join()
11311163
except:
11321164
pass
1133-
if self.delay_thread is not None:
1134-
try:
1135-
self.delay_thread.cancel()
1136-
except:
1137-
pass
1165+
self._stop_delay_thread()
11381166
if self.process is not None:
11391167
if platform.startswith('win'):
11401168
try:
@@ -1165,11 +1193,7 @@ def toggleMute(self):
11651193
self.muted = not self.muted
11661194
self._mute()
11671195
if self.muted:
1168-
if self.delay_thread is not None:
1169-
try:
1170-
self.delay_thread.cancel()
1171-
except:
1172-
pass
1196+
self._stop_delay_thread()
11731197
self.title_prefix = '[Muted] '
11741198
self.show_volume = False
11751199
else:
@@ -1691,7 +1715,6 @@ class VlcPlayer(Player):
16911715
WIN = False
16921716
if platform.startswith('win'):
16931717
WIN = True
1694-
logger.error('DE WIN = {}'.format(WIN))
16951718
PLAYER_CMD = "cvlc"
16961719
if WIN:
16971720
# TODO: search and finde vlc.exe
@@ -1708,8 +1731,6 @@ class VlcPlayer(Player):
17081731
else:
17091732
executable_found = False
17101733

1711-
print('executable: {}'.format(REAL_PLAYER_CMD))
1712-
17131734
if executable_found:
17141735
""" items of this tupple are considered icy-title
17151736
and get displayed after first icy-title is received """
@@ -1734,7 +1755,7 @@ class VlcPlayer(Player):
17341755
max_volume = 512
17351756

17361757
""" When found in station transmission, playback is on """
1737-
_playback_token_tuple = ('main audio ', 'Content-Type: audio' )
1758+
_playback_token_tuple = ('main audio ', 'Content-Type: audio', ' Segment #' )
17381759

17391760
""" Windows only variables """
17401761
_vlc_stdout_log_file = ''
@@ -1951,7 +1972,6 @@ def _req(self, msg, ret_function=None, full=True):
19511972
try:
19521973
while (True):
19531974
received = (sock.recv(4096)).decode()
1954-
#print('received: "{}"'.format(received))
19551975
response = response + received
19561976
if full:
19571977
if response.count("\r\n") > 1:
@@ -1963,7 +1983,6 @@ def _req(self, msg, ret_function=None, full=True):
19631983
break
19641984
except:
19651985
response = response + received
1966-
pass
19671986
sock.close()
19681987
except:
19691988
pass

0 commit comments

Comments
 (0)