5067 comments
2220 subscribers
4798 on Twitter
Subscribe! Feed reader E-mail

Quantified Awesome: How much music do you have?

I don’t listen to music a lot. Words interfere with my programming or writing (hmm, I should test to see how big the effect is), and I got used to working in silence or with white noise. Some people have a lot of music, though. R. Galacho wrote this Python script that uses the ID3 information in MP3s to sum up listening time in each genre, and wanted me to share it in case anyone else might find it useful:

# -*- coding: utf-8 -*-

__doc__="""
muasure v.0.1

How long could you listen...  Many times I've talked with friends about
my digital record collection's size (mmm... we are talking in the
order of GB) and how long could I've been listen if I make a playlist
with the hole collection and play it completely.  Well, I made some
mind calculations setting up average time and making a proportion to
the number of files taken in my HDD.

So, spare time and the speed and versatility inherent to Python give me
the rest.

Music Measure (Muasure for short) calculates the total time of your
music collection. Finally show data in screen and writes a text file
with that information into collection base directory (so if you clean
your screen you don't have to relaunch the process).

The only parameter expected is the base location of your record
collection (by default is the current directory when invoked).

Written, tested, runned and commited on GNU Emacs 23.2.1 (i686-pc-linux-gnu, GTK+ Version 2.24.4) ;)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
__author__="R. Galacho"
__version__="0.0.1"
__date__="20111010"

import os, sys, re
from datetime import timedelta
from mutagen.mp3 import MP3, HeaderNotFoundError
from collections import OrderedDict
from cStringIO import StringIO

def get_total_time(directory, collection):
    content_types = dict()
    lengths = 0
    for mp3_file in collection:
        try:
            id3v = MP3(mp3_file)
            lengths += id3v.info.length
            content = str(id3v.get('TCON'))
            if content_types.get(content) == None:
                content_types[content] = id3v.info.length
            else:
                content_types[content] += id3v.info.length
        except HeaderNotFoundError:
            sys.stderr.write("Error reading file %s\n" % mp3_file)

    total_time = timedelta(seconds = lengths)
    avg_length = timedelta(seconds = float(lengths / len(collection)))
    file_str = StringIO()

    file_str.writelines(["Total time  : ", str(total_time), "\nAverage time: ", str(avg_length), "\n\n"])
    ord_content_types = OrderedDict(sorted(content_types.items(), key=lambda t: t[1], reverse=True))
    for (k, v) in ord_content_types.items():
        total_time = timedelta(seconds = content_types.get(k))
        file_str.writelines([k.ljust(15), ": ", str(total_time),"\n"])

    print file_str.getvalue()
    if os.access(directory, os.W_OK):
        result_file = open(('%s%smuasure-data.txt' % (directory, os.sep)), 'w')
        result_file.write(file_str.getvalue())
        result_file.flush()
        result_file.close()

    file_str.close()

def main(collection_dir):
    directory = os.path.expanduser(collection_dir)

    if not os.access(directory, os.R_OK):
        raise Exception("Not enough permission on %s" % directory)

    collection = []
    pattern = re.compile(r'\.mp3')

    for dir, subdirs, files in os.walk(directory):
        collection.extend("%s%s%s" % (dir, os.sep, f) for f in filter(lambda x: pattern.search(x), files))

    collection = map(os.path.abspath, collection)
    get_total_time(directory, collection)

if __name__ == "__main__":
    if len(sys.argv) > 1:
        main(sys.argv[1])
    else:
        main("./")

This requires Python 2.6 or later and Python-mutagen 1.19 or later.

What else can you automatically extract from the files or data you already have? People have done interesting analyses based on geocoded photos, times of tweets, and so on. Have fun exploring!

Short URL: http://sachachua.com/blog/p/22599

Comment, share a thought, ask a question...

Please comment as you, not your organization.





 

On This Day...

  • 2010: Weekly review: Week ending November 7, 2010 — From last week’s plans Work [X] Work on yearly review documentation [X] Give presentation on social media [...]
  • 2009: Five types of coaching — Influenced by the work of Hargrove, most coaching today fits within one of five categories: Expert coaching: building skills, competencies, and [...]
  • 2007: Setting up appointment reminders in Org — Although the agenda view is very handy, it is generally not a good idea to check the agenda view every three [...]
  • 2007: Planning my career – first stages — It’s much easier to act than it is to react, and it’s less stressful too. When you have goals and clear [...]
  • 2006: Tom Purves, Enterprise 2.0 overview — I’m at Enterprise2.0Camp right now. Tom Purves gave a good overview of what Enterprise 2.0 is and what it means for businesses. [...]
  • 2006: Oct 30, 2006 to Nov 5, 2006 — School and learning I spent the week steadily working on various school deliverables – CAS project report, KMD2004 essay on open source [...]
  • 2005: Teaching needs small classes — Next, in terms of classroom teaching, there have got to be small classes. What kind of education is it, like [...]
  • 2004: Open source — I think one of the most amazing things about open source is the way it allows people to make a difference [...]
  • 2004: Yaaay! Skype works! — A very big thank you to arete of irc://irc.freenode.net/#emacs for his patience in helping me test the system. My Skype ID is [...]
  • 2004: My ref-filter script — #/usr/bin/perl my $s; while ($s = ) { if ($s =~ /.+?\"GET ([^ ]+) .+?".+?"([^"]+)/) [...]