29

So i have the code:

import glob,os
import random


path = 'C:\\Music\\'
aw=[]
for infile in glob.glob( os.path.join(path,'*.mp3') ):
    libr = infile.split('Downloaded',1)



    aw.append(infile)
aww = -1
while 1:
    aww += 1
    print len(aw),aww

    random.shuffle(aw)
    awww = aw[aww]
    os.startfile(awww)

but all it does is go through all of the songs without stopping. I thought if I could find the length of the song that is currently playing, I could use the "time" module to keep going after the song is done with the (sleep) attribute. However, I couldn't find how to get the length of the song on windows. Does anyone know a solution to my probleme?

hippietrail
  • 14,735
  • 16
  • 96
  • 147
P'sao
  • 2,666
  • 10
  • 36
  • 46
  • 4
    Your question title is confusing. Perhaps this is part of a shuffle music player, but your problem is finding the length of an mp3 song. Also, your variable names (`aw`, `aww`, `awww`) could be more descriptive ;-) – Gregg May 17 '11 at 22:48

5 Answers5

74

You can use mutagen to get the length of the song (see the tutorial):

from mutagen.mp3 import MP3
audio = MP3("example.mp3")
print(audio.info.length)
Tomasz Gandor
  • 7,235
  • 2
  • 55
  • 51
Gregg
  • 3,016
  • 19
  • 15
  • 2
    @salks: It should. Extract the archive, `cd` into the directory, and run `python setup.py install` from the command line. – Gregg May 17 '11 at 23:36
  • RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning) Traceback (most recent call last): File "E:\PythonProjects\testfile.py", line 11, in print(file.info.length) AttributeError: 'str' object has no attribute 'info' – Moses Oct 20 '21 at 10:18
13

You can use FFMPEG libraries:

    args=("ffprobe","-show_entries", "format=duration","-i",filename)
    popen = subprocess.Popen(args, stdout = subprocess.PIPE)
    popen.wait()
    output = popen.stdout.read()

and the output will be:

[FORMAT]
duration=228.200515
[/FORMAT]
Gabriel Furstenheim
  • 2,455
  • 23
  • 22
4

You can also get this using eyed3, if that's your flavor by doing:

import eyed3
duration = eyed3.load('path_to_your_file.mp3').info.time_secs

Note however that this uses sampling to determine the length of the track. As a result, if it uses variable bit rate, the samples may not be representative of the whole, and the estimate may be off by a good degree (I've seen these estimates be off by more than 30% on court recordings).

I'm not sure that's much worse than other options, but it's something to remember if you have variable bit rates.

mlissner
  • 16,103
  • 17
  • 95
  • 162
4

Newer versions of python-ffmpeg have a wrapper function for ffprobe. An example of getting the duration is like this:

import ffmpeg
print(ffmpeg.probe('in.mp4')['format']['duration']))

Found at: https://github.com/kkroening/ffmpeg-python/issues/57#issuecomment-361039924

Joseph
  • 215
  • 2
  • 11
0

Maybe do the playing also within Python, i.e. don't use os.startfile, use some Python library to play the file.

I have recently written such a library/module, the musicplayer module (on PyPI). Here is a simple demo player which you can easily extend for your shuffle code.

Just do easy_install musicplayer. Then, here is some example code to get the length:

class Song:
    def __init__(self, fn):
        self.f = open(fn)
    def readPacket(self, bufSize):
        return self.f.read(bufSize)
    def seekRaw(self, offset, whence):
        self.f.seek(offset, whence)
        return self.f.tell()

import musicplayer as mp

songLenViaMetadata = mp.getMetadata(Song(filename)).get("duration", None)
songLenViaAnalyzing = mp.calcReplayGain(Song(filename))[0]
Albert
  • 61,575
  • 58
  • 224
  • 362