41

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
  • 15,848
  • 18
  • 99
  • 158
P'sao
  • 2,946
  • 11
  • 39
  • 48
  • 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

95

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
  • 8,235
  • 2
  • 60
  • 55
Gregg
  • 3,236
  • 20
  • 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
  • Bad solution, esp. for being selectd as the best one! mutagen' is for audio only. 'ffmpeg' on the other hand is for both audio and video. So why installing and using a module that has a restricted use? – Apostolos Jul 11 '23 at 11:57
14

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,969
  • 30
  • 27
8

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
  • 293
  • 4
  • 12
  • Definitely the best solution and it should be selected as such. (BTW, the command print(ffmpeg.probe('in.mp4')['format']['duration'])) has an extra parenthesis at the end.) – Apostolos Jul 11 '23 at 12:00
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
  • 17,359
  • 18
  • 106
  • 169
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
  • 65,406
  • 61
  • 242
  • 386