It appears that the mp3play module uses the Windows winmm library. Specifically, it uses function mciSendString
to control the multimedia system.
One option to achieve what you want would be to use the status
command to periodically retrieve the current playback position and display it as you like.
It would seem most appropriate to modify both versions of the AudioClip
class from the mp3play library.
Modifying mp3play Library
Class AudioClip in windows.py
First, on line 59 of windows.py you can see a function that uses the status command
def _mode(self):
err, buf = self._mci.directsend('status %s mode' % self._alias)
return buf
We can write a new function based on this example, which will get the current playback position:
def current_position(self):
err, buf = self._mci.directsend('status %s position' % self._alias)
return buf
This function will return a string encoding a number representing the current position in milliseconds.
Class AudioClip in init.py
The next step is to modify AudioClip
class on line 12 of __init__py, adding the following function:
def current_position(self):
"""Get current position of clip in milliseconds."""
return int(self._clip.current_position())
CLI Example
Now we can test it with a simple script:
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()
The console output looks as follows:
>python test.py
Position: 0 / 174392
Position: 905 / 174392
Position: 1906 / 174392
Position: 2906 / 174392
Position: 3907 / 174392
GUI Example
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()
Screenshot:
