Here's an alternative way to do it (python 3), using multiprocessing. Note, to get the stdin to work in the child process, you have to re open it first. I'm also converting the input from string to int to use with the multiprocessing value, so you might want to error check there as well.
import multiprocessing as mp
import time
import sys
import os
TIMEOUT = 10
DEFAULT = 3
def get_input(resp: mp.Value, fn):
sys.stdin = os.fdopen(fn)
v = input('change music(1) or close the app (2)')
try:
resp.value = int(v)
except ValueError:
pass # bad input, maybe print error message, try again in loop.
# could also use another mp.Value to signal main to restart the timer
if __name__ == '__main__':
now = time.time()
end = now + TIMEOUT
inp = 0
resp = mp.Value('i', 0)
fn = sys.stdin.fileno()
p = mp.Process(name='Get Input', target=get_input, args=(resp, fn))
p.start()
while True:
t = end - time.time()
print('Checking for timeout: Time = {:.2f}, Resp = {}'.format(t, resp.value))
if t <= 0:
print('Timeout occurred')
p.terminate()
inp = DEFAULT
break
elif resp.value > 0:
print('Response received:', resp.value)
inp = resp.value
break
else:
time.sleep(1)
print()
if inp == 1:
print('Music Changed')
elif inp == 2:
print('Good Bye')
else:
print('Other value:', inp)