diff -ur v1/snddiv.py v2/snddiv.py --- v1/snddiv.py 2020-01-19 16:07:27.000000000 +0900 +++ v2/snddiv.py 2020-01-19 16:31:38.000000000 +0900 @@ -2,13 +2,18 @@ import sys import os +import time import yaml +import select +import threading import empty import cmd_ut import thr import dbg +readable = lambda fd, tmout=3.0: select.select([fd], [], [], tmout)[0] == [fd] + def data_new(name_mp3): (name, mp3) = os.path.splitext(name_mp3) @@ -84,10 +89,96 @@ return empty.new( locals() ) +def play_new(dat, opt, r_rate=1.0): + e = empty.new() + e.dat = dat + e.run = False + e.sec = 0 + e.rbuf = '' + e.evt = threading.Event() + + last_sec = opt.byte_to_sec( len(dat) ) + + def proc_new(): + sudo_passwd = '' + cmd = 'play {} -'.format( opt.get_raw_opt(r_rate) ) + if sudo_passwd: + cmd = 'sudo -S ' + cmd + PIPE = cmd_ut.PIPE + proc = cmd_ut.proc_new(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) + if sudo_passwd: + proc.write_stdin_flush( sudo_passwd + '\n' ) + return proc + + def update(): + s = e.rbuf + if not s.startswith('In:'): + return + lst = s.split()[1:2] + if not lst: + return + s = lst[0] + sec = 0 + for v in map( float, s.split(':') ): + sec *= 60 + sec += v + if sec >= last_sec: + e.run = False + e.sec = sec + e.evt.set() + + def rfunc(f): + if not ( e.run and readable(f) ): + return + c = f.read(1) + if not c: + return + c = c.decode() + e.rbuf += c + if c in '\n\r': + update() + e.rbuf = '' + + def wfunc(f): + try: + f.write(dat) + except: + pass + f.close() + + proc = proc_new() + rth = thr.loop_new( rfunc, ( proc.get_stderr(), ) ) + wth = thr.th_new( wfunc, ( proc.get_stdin(), ) ) + + def start(): + e.run = True + rth.start() + wth.start() + + def stop(): + e.run = False + proc.kill() + rth.stop() + wth.stop() + proc.wait() + + return empty.to_attr( e, locals() ) + if __name__ == "__main__": if not sys.argv[1:]: dbg.err_exit( 'Usage: {} filename_mp3'.format( sys.argv[0] ) ) data = data_new( sys.argv[1] ) dbg.out( 'last_sec={}'.format( data.last_sec ) ) + + opt = data.opt + dat = data.get_dat_sec(10, False) + play = play_new(dat, opt) + + while True: + dbg.out('snd> ', '') + s = sys.stdin.readline() + if not s: + break + exec(s) # EOF