【问题标题】:Progressbar to show amount of music played进度条显示播放的音乐量
【发布时间】:2016-09-30 10:39:30
【问题描述】:

假设我使用mp3play 模块播放mp3 文件,使用ttk.Progressbar,我想显示播放音乐的数量(持续时间)。有什么代码可以实现吗?

我还想要一个计时器 a 来显示播放音乐的时长。

import ttk
import mp3play
self.music = mp3play.load('filename')
self.fr=ttk.Frame()
self.fr.pack(expand=True, fill=BOTH, side=TOP)
self.seek=ttk.Progressbar(self.fr, orient='horizontal', mode='determinate', length=500)
self.seek.place(x=50, y=325)
self.seek.start()

【问题讨论】:

    标签: python python-2.7 tkinter


    【解决方案1】:

    查看mp3playmodule的代码,mp3play.load()返回一个AudioClip对象。该对象具有 seconds()milliseconds() 方法,它们分别以秒或毫秒为单位提供剪辑的长度。

    您可以保存开始播放的时间,并将其与当前时间和剪辑的总长度进行比较,以确定进度条的状态。

    # assuming time would me measured in milliseconds
    start = time()
    while playing:
        # progress measured in percentages
        progress = 100 * (time() - start)/ clip.milliseconds()
    

    【讨论】:

    • 不工作的人可以用正确的代码解释我吗,还有一件事 mp3play.load.seconds() 返回错误的持续时间,例如我测试了持续时间为 4:36 的 mp3 文件分钟,它返回 6:29 分钟 @Nysten
    【解决方案2】:

    看来 mp3play 模块 uses Windows winmm 库。具体来说,它使用函数mciSendStringcontrol多媒体系统。

    实现您想要的一个选项是使用status 命令定期检索当前播放位置并根据需要显示它。

    从 mp3play 库中修改 AudioClip 类的两个版本似乎是最合适的。


    修改 mp3play 库

    windows.py 中的音频剪辑类

    首先,在59 of windows.py 行,你可以看到一个使用状态命令的函数

        def _mode(self):
            err, buf = self._mci.directsend('status %s mode' % self._alias)
            return buf
    

    我们可以根据这个例子写一个新函数,获取当前播放位置:

        def current_position(self):
            err, buf = self._mci.directsend('status %s position' % self._alias)
            return buf
    

    此函数将返回一个字符串,该字符串编码一个表示当前位置的数字,以毫秒为单位。

    init.py

    ​​> 中的类 AudioClip

    接下来修改AudioClip线上12 of __init__py的类,添加如下函数:

        def current_position(self):
            """Get current position of clip in milliseconds."""
            return int(self._clip.current_position())
    

    CLI 示例

    现在我们可以用一个简单的脚本来测试它:

    import time
    import mp3play
    
    clip = mp3play.load(r'test.mp3')
    
    clip.play()
    
    for i in range(5):
        print "Position: %d / %d" % (clip.current_position(), clip.milliseconds())
        time.sleep(1)
    
    clip.stop()
    

    控制台输出如下:

    >python test.py
    Position: 0 / 174392
    Position: 905 / 174392
    Position: 1906 / 174392
    Position: 2906 / 174392
    Position: 3907 / 174392
    

    图形用户界面示例

    import tkinter as tk
    from tkinter import ttk
    
    import mp3play
    
    # ================================================================================
    
    def format_duration(ms):
        total_s = ms / 1000
        total_min = total_s / 60
        remain_s = total_s % 60
        return "%0d:%02d" % (total_min, remain_s)
    
    # ================================================================================
    
    class SimplePlayer(tk.Tk):
    
        def __init__(self, *args, **kwargs):
            tk.Tk.__init__(self, *args, **kwargs)
    
            # Variables we use to dynamically update the text of the labels
            self.music_title = tk.StringVar()
            self.music_progress = tk.StringVar()
    
            self.fr=ttk.Frame()
            self.fr.pack(expand=True, fill=tk.BOTH, side=tk.TOP)
    
            # Label to display the song title
            self.title_lbl = ttk.Label(self.fr, textvariable = self.music_title)
            self.title_lbl.pack()
    
            # Playback progress bar
            self.progress_bar = ttk.Progressbar(self.fr, orient='horizontal', mode='determinate', length=500)
            self.progress_bar.pack()
    
            # Shows the progress numerically
            self.progress_lbl = ttk.Label(self.fr, textvariable = self.music_progress)
            self.progress_lbl.pack()
    
    
        def start(self, music_file):
            self.music = mp3play.load(music_file)
    
            # Update the title
            self.music_title.set(music_file)
    
            # Start playback
            self.music.play()
    
            # Start periodically updating the progress bar and progress label
            self.update_progress()
    
        def update_progress(self):
            pos_ms = self.music.current_position()
            total_ms = self.music.milliseconds()
            progress_percent = pos_ms / float(total_ms) * 100
    
            # Update the label
            label_text = "%s / %s   (%0.2f %%)" % (format_duration(pos_ms), format_duration(total_ms), progress_percent)
            self.music_progress.set(label_text)
    
            # Update the progress bar
            self.progress_bar["value"] = progress_percent
    
            # Schedule next update in 100ms        
            self.after(100, self.update_progress)
    
    # ================================================================================
    
    app = SimplePlayer()
    
    app.start('test.mp3')
    app.mainloop()
    

    截图:

    【讨论】:

    • 你能用代码解释我吗,例如文件的代码以及如何将它合并到进度条@DanMasek
    • @TigerKing 好的,你去。
    • 你能解释一下“self.music.current_position()”bcoz mp3play 没有像 current_position() @DanMasek 这样的属性
    • @TigerKing 您需要修改mp3play库并添加这些功能,如答案第一部分所述。
    • 感谢您提供的所有帮助,但还有一个错误,您在代码中写了一行label_text = "%s / %s (%0.2f %%)" % (format_duration(pos_ms), format_duration(total_ms), progress_percent),但是当我将其合并到我的程序中时,python 说global name 'format_duration' is not defined@DanMasek
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    相关资源
    最近更新 更多