Found the problem: the issue is stderr=subprocess.PIPE. When ffmpeg runs for a few minutes, it fills up the pipe, and since there's no ps.communicate() to clear it, eventually the process just stalls. 2 simplest ways to solve this:
read the output from the pipe:
ps = subprocess.Popen(cmd,stderr=sb.PIPE)
ps.communicate()
or send all output to /dev/null:
devnul = open(os.devnull,"w") #this is multiplatform, rather than hardocding "/dev/null"
ps = sb.Popen(cmd,stderr=devnul)
#....
#some other code here, eventually kill the process maybe
#....
devnul.close()
(assuming subprocess was imported as sb)