Day-to-day problem solving with python

Building a music Downloader and meta data updating script — PART I

This is my very first medium publish, and the first in the series ( Atleast I hope it will be :P), day-to-day​ problem solving with python. Python is really a unique language, call it slow or whatever, it does the job neatly and that is undeniable. It feels close to JS, and it’s so familiar looking syntax makes it a perfect choice for coding day-to-day problems. So let’s give it a try.

We will be writing a script for music downloading and automatic metadata update. We will also download and attach proper album art. I will try to cover the entire project in 3 or 4 posts.

For starters,

Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python's elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.

Let’s build

Hope you are familiar with python packages or modules. The core of this application is a python package youtube_dl. “Youtube_dl” is a command line utility as well as python package used for downloading YouTube videos. Its a fairly simple yet powerful package, with built in support for audio extraction and more.

Our project can be split into,

  1. Downloading songs
  2. Downloading relevant album art
  3. Updating ID3 and embedding album art

I will be covering each of them in separate posts, so stay tuned.

Coding the downloading scrpit

First of all the module imports,

__future__ is used for importing python3 features to python2.

GIS and ID3update will be discussed in the upcoming posts. No need to import them right now.


The idea here is fairly simple, take input from user for song title, artist name and the album. These are not compulsory fields.

Remember, python2 has two input methods, raw_input() and input(). raw_input() simply takes string input and performs no evaluation whereas input() evaluates the given input and take int type input values or expressions. But for python3 there is only input() method which works similar to raw_input() in python2. For evaluation you can use eval(input()).

Finally we generate a keyword that is formed by concatenating these 3 inputs with a special character in between(‘@’ for example). The reason for doing this is fairly simple. We will build functions which need these 3 inputs, but passing 3 different arguments feels cumbersome. So we pass 1 argument, i.e the keyword and extract the details when needed using .split()

Here is the code,

Now the task is actually creating a YouTube search query and searching YouTube for results. So we define a function called search() and pass in the keyword as argument.

Here is the function,

urllib2.quote() converts normal whitespace containing text into URL query. The inner argument simply removes the special character ‘@’. Then we open the URL, read the response and parse the HTML using beautiful soup.

Now let’s grab all the links on the searched page. This function takes one argument i.e. the parsed HTML. All the links are appended to a list named songs.

Time to display these titles to the user and asking him, which one to download. It’s always a good idea to take user input here since YouTube search may interpret the search query in a wrong manner. This could be due to less details provided or the song being less popular and we may end up with wrong downloads.

Now for the most important thing, downloading the mp3.

Youtube_dl accepts certain options as a list argument. There are numerous options available but for our task this would look like,

Almost everything is straightforward except for the logger and the progress_hooks. Let’s talk about them in detail


YouTube_dl has a logging option for logging debug messages, warnings, and errors to the terminal. MyLogger is a class with methods for debug, warning and error and can be configured in the program itself.

Progress hooks

As the name suggests this are hooks attached with the progress of the download. Sounds simple, doesn’t it XD.

Ok seriously, it’s nothing but a function that takes in a dictionary with keys like downloaded bytes, eta, download speed, total size etc.

We will use it to display the download progress.

Preparations almost done, lets start downloading. Just two lines and boom, all done.

That is it, your song is ready to download. Let’s put them all together to create our very own mp3 downloader. Let’s call these functions.

Just run the script and enjoy. In the next part we will see how to download the album art for the song. I hope it was fun, and feel free to ask me any doubts at