【发布时间】:2020-07-27 03:45:51
【问题描述】:
我已经阅读了已回答的类似问题:
- Getting realtime output from ffmpeg to be used in progress bar (PyQt4, stdout)
- Progressbar to show amount of music played
- How to measure elapsed time in Python?
这是我的窗口:
问题是当计数器还有 20% 的时候歌曲结束。我知道原因主要是由于系统调用检查进程是否仍在运行 pgrep ffplay 每秒 10 次。次要原因仅仅是 Python 和 Tkinter 开销。
为了“创可贴”,我使用1.24 deciseconds 而不是1 每十秒的问题,正如我的代码现在所示:
def play_to_end(self):
'''
Play single song, checking status every decisecond
Called from:
self.play_forever() to start a new song
self.pp_toggle() to restart song after pausing
'''
while True:
if not self.top2_is_active: return # Play window closed?
root.update() # Process other events
if self.pp_state is "Paused":
time.sleep(.1) # Wait until playing
continue
PID = os.popen("pgrep ffplay").read() # Get PID for ffplay
if len(PID) < 2: # Has song ended?
return # Song has ended
#self.current_song_time += .1 # Add decisecond
self.current_song_time += .124 # Add 1.24 deciseconds
# compensatation .24
self.current_progress.set(str('%.1f' % self.current_song_time) + \
" seconds of: " + str(self.DurationSecs))
root.update() # Process other events
root.after(100) # Sleep 1 decisecond
这个创可贴修复的问题在于它高度依赖机器。例如,我的机器是 Skylake。此外,它高度依赖于同时运行的其他进程。测试时我的机器负载相对较轻:
我如何以编程方式计算损失的时间,以便准确地增加经过的时间?
也许有更好的方法来简单地查询ffplay 以了解歌曲进度?
顺便说一句(我知道一次问两个问题是不受欢迎的)为什么我不能简单地检查PID 是否为空?我在.read() 之后尝试了.rstrip() 和.strip() 无济于事,检查PID 等于"" 或None。如果ffplayevery 在10 下有一个进程ID,程序就会出现异常。
【问题讨论】:
-
你在 tkinter 中尝试过
.after()吗? -
@jizhihaoSAMA 是的,最初的设计是使用
.after()引用各种框架和标签等。我放弃并使用root.after,它似乎总是有效,并且在最后一行代码。不过,这对时间补偿没有帮助...... -
如何启动
ffplay?使用subprocess.Popen()? -
@acw1668 第一行是
os.popen('ffplay -autoexit ' + '"' + self.current_song_path + '"'续第二行:+ ' -nodisp 2>' + TMP_CURR_SONG + ' &') -
尝试使用
subprocess.Popen()而不是os.popen()并将stderr重定向到PIPE,然后您可以阅读stderr以更新进度。
标签: python tkinter elapsedtime wall-time