Progressbar to show amount of music played
<p>Suppose I use <code>mp3play</code> module to play mp3 files, and using <code>ttk.Progressbar</code>, I want to show the amount(duration) of music played. Is there any code to achieve it?  </p>

<p>I also want a timer a to show the duration of music played.</p>

<pre><code>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()
</code></pre>

<p>It appears that the mp3play module <a href="https://github.com/michaelgundlach/mp3play/blob/master/mp3play/windows.py" rel="nofollow">uses</a> the Windows <a href="https://msdn.microsoft.com/en-us/library/vs/alm/dd743606(v=vs.85).aspx" rel="nofollow">winmm</a> library. Specifically, it uses function <a href="https://msdn.microsoft.com/en-us/library/vs/alm/dd757161(v=vs.85).aspx" rel="nofollow"><code>mciSendString</code></a> to <a href="https://msdn.microsoft.com/en-us/library/vs/alm/dd743572(v=vs.85).aspx" rel="nofollow">control</a> the multimedia system.</p>

<p>One option to achieve what you want would be to use the <a href="https://msdn.microsoft.com/en-us/library/vs/alm/dd798683%28v=vs.85%29.aspx?f=255&amp;MSPPError=-2147217396" rel="nofollow"><code>status</code></a> command to periodically retrieve the current playback position and display it as you like.</p>

<p>It would seem most appropriate to modify both versions of the <code>AudioClip</code> class from the mp3play library.</p>

<hr>

<h1>Modifying mp3play Library</h1>

<h2>Class AudioClip in windows.py</h2>

<p>First, on line <a href="https://github.com/michaelgundlach/mp3play/blob/master/mp3play/windows.py#L59" rel="nofollow">59 of windows.py</a> you can see a function that uses the status command</p>

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

<p>We can write a new function based on this example, which will get the current playback position:</p>

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

<p>This function will return a string encoding a number representing the current position in milliseconds.</p>

<h2>Class AudioClip in <strong>init</strong>.py</h2>

<p>The next step is to modify <code>AudioClip</code> class on line <a href="https://github.com/michaelgundlach/mp3play/blob/master/mp3play/__init__.py#L12" rel="nofollow">12 of __init__py</a>, adding the following function:</p>

<pre><code>    def current_position(self):
        """Get current position of clip in milliseconds."""
        return int(self._clip.current_position())
</code></pre>

<hr>

<h1>CLI Example</h1>

<p>Now we can test it with a simple script:</p>

<pre><code>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()
</code></pre>

<p>The console output looks as follows:</p>

<pre><code>&gt;python test.py
Position: 0 / 174392
Position: 905 / 174392
Position: 1906 / 174392
Position: 2906 / 174392
Position: 3907 / 174392
</code></pre>

<hr>

<h1>GUI Example</h1>

<pre><code>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()
</code></pre>

<p>Screenshot: </p>

<p><img src="http://i.imgur.com/J8rmTgx.png" alt="Screenshot of running GUI example"></p>

python python-2.7 tkinter