Skip to content

Commit b093287

Browse files
committed
Merge pull request #47 from thomasleveil/popen-non-slave/mpv-status
display progress status for both mplayer and mpv
2 parents 7999cc0 + f57ba98 commit b093287

File tree

1 file changed

+96
-57
lines changed

1 file changed

+96
-57
lines changed

mpsyt

Lines changed: 96 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,37 @@ non_utf8 = mswin or not "UTF-8" in os.environ.get("LANG", "")
8888
member_var = lambda x: not(x.startswith("__") or callable(x))
8989
locale.setlocale(locale.LC_ALL, "") # for date formatting
9090

91+
# A: 175.6 (02:55.5) of 258.8 (04:18.7) 0.0%
92+
re_mplayer_audio_status = re.compile(r"""
93+
A:\s*(?:[0-9.]+)?
94+
\s+\(
95+
(?:(?P<elapsed_h>\d+):)??
96+
(?:(?P<elapsed_m>\d+):)?
97+
(?P<elapsed_s>\d+)
98+
(?:\.[0-9]+)?
99+
\)\s+of\s+
100+
(?:[0-9.]+)?
101+
\s+\(
102+
(?:(?P<total_h>\d+):)??
103+
(?:(?P<total_m>\d+):)?
104+
(?P<total_s>\d+)
105+
(?:\.[0-9]+)?
106+
\)
107+
""", re.VERBOSE)
108+
109+
# A: 00:00:07 / 00:05:37 (2%) Cache: 46%
110+
# AV: 00:00:03 / 00:03:30 (1%) A-V: -0.000 Cache: 14%
111+
re_mpv_status = re.compile(r"""
112+
AV?:\s*
113+
(?P<elapsed_h>\d+):
114+
(?P<elapsed_m>\d+):
115+
(?P<elapsed_s>\d+)
116+
\s+/\s+
117+
(?P<total_h>\d+):
118+
(?P<total_m>\d+):
119+
(?P<total_s>\d+)
120+
""", re.VERBOSE)
121+
91122

92123
def non_utf8_encode(txt):
93124
""" Encoding for non UTF8 environments. """
@@ -1236,45 +1267,36 @@ def playsong(song, failcount=0, override=False):
12361267
return
12371268

12381269
cmd, songdata = generate_real_playerargs(song, override)
1239-
stdout = stderr = None
12401270
now = time.time()
12411271
songdata = "%s; %s; %s Mb" % songdata
12421272
writestatus(songdata)
12431273

1244-
with open(os.devnull, "w") as fnull:
1274+
for quiet in ('-really-quiet', '--really-quiet'):
12451275

1246-
if "mpv" in Config.PLAYER or "mplayer" in Config.PLAYER:
1247-
stderr = fnull
1276+
try:
1277+
cmd.remove(quiet)
12481278

1249-
if mswin:
1250-
stdout = stderr = fnull
1279+
except ValueError:
1280+
pass
12511281

1252-
for quiet in ('-really-quiet', '--really-quiet'):
1282+
logging.info("playing %s (%s)", song.title, failcount)
1283+
dbg("calling %s", cmd)
12531284

1254-
try:
1255-
cmd.remove(quiet)
1256-
1257-
except ValueError:
1258-
pass
1285+
try:
1286+
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE,
1287+
stderr=subprocess.STDOUT, bufsize=1)
1288+
mplayer_status(p, songdata + ";")
12591289

1260-
logging.info("playing %s (%s)", song.title, failcount)
1261-
dbg("calling %s", cmd)
1290+
except OSError:
1291+
g.message = F('no player') % Config.PLAYER
1292+
return
12621293

1294+
finally:
12631295
try:
1264-
p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE,
1265-
stderr=stderr, bufsize=1)
1266-
mplayer_status(p, songdata + ";")
1267-
1268-
except OSError:
1269-
g.message = F('no player') % Config.PLAYER
1270-
return
1296+
p.terminate() # make sure to kill mplayer if mpsyt crashes
12711297

1272-
finally:
1273-
try:
1274-
p.terminate() # make sure to kill mplayer if mpsyt crashes
1275-
1276-
except:
1277-
pass
1298+
except:
1299+
pass
12781300

12791301
fin = time.time()
12801302
failed = fin - now < 1 and song.length > 1
@@ -1293,19 +1315,6 @@ def playsong(song, failcount=0, override=False):
12931315

12941316

12951317
def mplayer_status(popen_object, prefix=""):
1296-
1297-
# A: 175.6 (02:55.5) of 258.8 (04:18.7) 0.0%
1298-
re_mplayer_audio_status = re.compile(r"""
1299-
A:\s*(?P<sec>[0-9.]+)?
1300-
\s+
1301-
\((?P<elapsed_h>\d+:)??
1302-
(?P<elapsed_m>\d+:)?
1303-
(?P<elapsed_s>\d+)
1304-
(?P<elapsed_ms>\.[0-9]+)?\)
1305-
\s+of\s+
1306-
(?P<sec_total>[0-9.]+)?
1307-
""", re.VERBOSE)
1308-
13091318
buff = ''
13101319
last_displayed_line = None
13111320

@@ -1314,12 +1323,14 @@ def mplayer_status(popen_object, prefix=""):
13141323

13151324
if char in '\r\n':
13161325
m = re_mplayer_audio_status.match(buff)
1326+
if not m:
1327+
m = re_mpv_status.match(buff)
13171328

13181329
if m:
13191330
line = make_status_line(m)
13201331

13211332
if line != last_displayed_line:
1322-
writestatus(prefix + line)
1333+
writestatus(prefix + (" " if prefix else "") + line)
13231334
last_displayed_line = line
13241335

13251336
buff = ''
@@ -1328,34 +1339,62 @@ def mplayer_status(popen_object, prefix=""):
13281339
buff += char
13291340

13301341

1331-
def make_status_line(match_object):
1332-
1342+
def make_status_line(match_object, progress_bar_size=30):
1343+
"""
1344+
Assume match_object have groups:
1345+
- elapsed_h
1346+
- elapsed_m
1347+
- elapsed_s
1348+
- total_h
1349+
- total_m
1350+
- total_s
1351+
which hold either an empty string or an integer value as a string
1352+
1353+
>>> make_status_line(re_mplayer_audio_status.match("A: 0.0 (0.0) of 258.8 (04:18.7) 0.0%"))
1354+
'00:00:00 (0%) [>.............................]'
1355+
>>> make_status_line(re_mplayer_audio_status.match("A: 175.6 (02:55.5) of 258.8 (04:18.7) 0.0%"))
1356+
'00:02:55 (68%) [====================>.........]'
1357+
>>> make_status_line(re_mplayer_audio_status.match("A: 258.8 (04:18.7) of 258.8 (04:18.7) 0.0%"))
1358+
'00:04:18 (100%) [=============================>]'
1359+
1360+
>>> make_status_line(re_mpv_status.match("A: 00:00:00 / 00:05:37 (0%) Cache: 46%"))
1361+
'00:00:00 (0%) [>.............................]'
1362+
>>> make_status_line(re_mpv_status.match("A: 00:02:32 / 00:05:37 (45%) Cache: 60%"))
1363+
'00:02:32 (45%) [=============>................]'
1364+
>>> make_status_line(re_mpv_status.match("A: 00:05:37 / 00:05:37 (100%) Cache: 100%"))
1365+
'00:05:37 (100%) [=============================>]'
1366+
1367+
>>> make_status_line(re_mpv_status.match("AV: 00:00:00 / 00:03:30 (0%) A-V: -0.000 Cache: 14%"))
1368+
'00:00:00 (0%) [>.............................]'
1369+
>>> make_status_line(re_mpv_status.match("AV: 00:02:32 / 00:03:30 (73%) A-V: -0.000 Cache: 14%"))
1370+
'00:02:32 (72%) [=====================>........]'
1371+
>>> make_status_line(re_mpv_status.match("AV: 00:03:30 / 00:03:30 (100%) A-V: -0.000 Cache: 100%"))
1372+
'00:03:30 (100%) [=============================>]'
1373+
"""
13331374
try:
1334-
current = float(match_object.group('sec'))
1335-
1375+
elapsed_h = int(match_object.group('elapsed_h') or '0')
1376+
elapsed_m = int(match_object.group('elapsed_m') or '0')
1377+
elapsed_s = int(match_object.group('elapsed_s') or '0')
1378+
total_h = int(match_object.group('total_h') or '0')
1379+
total_m = int(match_object.group('total_m') or '0')
1380+
total_s = int(match_object.group('total_s') or '0')
13361381
except ValueError:
1337-
current = 0.0
1382+
return ""
13381383

1339-
try:
1340-
total = float(match_object.group('sec_total'))
1341-
1342-
except ValueError:
1343-
total = 0.0
1384+
current_sec = elapsed_h * 60 * 60 + elapsed_m * 60 + elapsed_s
1385+
total_sec = total_h * 60 * 60 + total_m * 60 + total_s
13441386

13451387
try:
1346-
pct = (current / total * 100)
1388+
pct = (float(current_sec) / total_sec * 100)
13471389

13481390
except ZeroDivisionError:
13491391
pct = 0
13501392

1351-
status_line = " %s%s%s %s" % (
1352-
match_object.group('elapsed_h') or '',
1353-
match_object.group('elapsed_m') or '00:',
1354-
match_object.group('elapsed_s'),
1393+
status_line = "%02i:%02i:%02i %s" % (
1394+
elapsed_h, elapsed_m, elapsed_s,
13551395
("(%.0f%%)" % pct).ljust(6)
13561396
)
13571397

1358-
progress_bar_size = 30
13591398
progress = int(ceil(pct / 100 * progress_bar_size))
13601399
status_line += " [%s]" % ("=" * (progress - 1) + ">").ljust(progress_bar_size, '.')
13611400

0 commit comments

Comments
 (0)