musicNet — A Windows App using Python and EEL

Sanskar Biswal
TheTeamMavericks
Published in
7 min readApr 10, 2020

Why Windows Apps?

It is a very pertinent question. There are hundreds of tools and packages available to develop apps for the web and mobile. Windows Apps are a little behind on the popularity wagon, however, Windows 10 is the most popular OS in the world and sometimes, it does get better to use a software on the system instead of a web browser or a phone.

In my student life, several hack-a-thons’ needed specialized front-end with a ton of programming capability, and ability to run natively on Windows. So, with that in mind, here is a tutorial to make a simple application using Python.

Python and EEL

Python Logo

Python is one of the most well-supported languages with a huge library to modules which allow you to do almost anything. Additionally it is easy to use and has a large community of developers and supported to fall back on if you face any issue.

EEL, on the other hand, is not as popular for making Python Apps, but it holds great potential. There are probably on two other tutorials available for EEL on the internet, which was one of the reasons for writing this blog. EEL is an Electron implementation on a pretty scaled down level. It is easy to use, and extremely efficient. As it so happens, it makes use of HTML\CSS\JS for developing the front-end.

So not only do you get a great code flexibility with python, your front-end will look extremely good, with very little effort.

musicNet — An Simple yet Elegant Music Player

The project we will be building is a simple music player. The app we develop is called musicNet. musicNet allows users to create multiple profiles and each profile to hold multiple playlists. The songs however do not reference to a library. Instead, if there is a music video you like, musicNet takes the URL of the video and generates the URL to the audio file. This URL is added to your playlist and stored locally. Next time you find yourself wanting some music from your favorite video, use musicNet without searching for those videos online. Better still, you can use this for audio books and online podcasts.

This tutorial blog is going to be in two parts. In this blog we will develop the frontend using EEL and write the code to play music from the URL provided by the user.

In the next blog, we will get into the intricacies of creating user profiles and managing playlists. So, let’s get started.

Setting up your Python environment

I am using Python 3.7.4 as my primary python version. You can develop this project on any version of Python3x. To know which version of Python you are running, open up your terminal(command prompt in Windows) and type the following in it:

$ python --version
Check Python Version in Terminal

You should get your version info. This will only work if Python is added to your PATH variables. To add python to PATH, you can follow the following tutorial (https://geek-university.com/python/add-python-to-the-windows-path/)

Next we will setup out virtual environment. A virtual environment is a great way of sand-boxing the different modules across all python projects. Ideally, every python project should have its own virtual environment. Check if virtual environment is installed.

$ virtualenv --version

If you get an error, it means that virtual environment is not installed. This can be done simply using the following command.

$ python -m pip install virtualenv

This command will get the virtualenv modules set up for you. Now that we have the tools, to set up the virtualenv, navigate inside your project directory in the terminal and type:

$ virtualenv venv

This will generate a virtualenv with name venv. The system needs to know that it needs to use the python version in venv and not the one installed on the local machine. To do this, we must activate the virtual environment.

On Windows
$ venv\Scripts\activate
On Linux
$ source venv/bin/activate

Once you do this your terminal should display something like this:

(venv) $ 

Installing the required Modules and setting Project Structure

We now need to install modules that will allow us to convert the video URL to obtain the audio URL, setup EEL module

(venv) $ pip install eel pafy youtube-dl

This will install EEL, pafy and youtuble-dl. Next let us establish our project structure.

musicNet
|- venv
|- web
|- css
|- main.css
|- js
|- main.js
|- img
|- main.html
|- main.py

To learn how to use EEL, refer to the following link (https://github.com/samuelhwilliams/Eel)

Python Script

Create EEL Application

"""
@brief main.py
"""
import eel
eel.init('web') # directory of web frontend#function to test connection with JS
@eel.expose
def test():
print("Testing")
#function to smoothly exit application
#eel returns two arguments, so function needs to handle them
@eel.expose
def handle_exit(ar1,ar2):
import sys
sys.exit(0)
# start EEL App
if __name__ == "__main__":
size = (1000,700) #size of App Window
app_opt = {
'mode' : "chrome",
'close_callback" : handle_exit
}
eel.start('main.html', options=app_opt, size=size, suppress_error=True)

To run the application

(venv) $ python main.py

This will open up a new windows which is blank. The title-bar will read local-host. During the testing phase, we will use run the app on the local host, but once we are completed with the project we will package it into a windows executable file.

Make Python Function to generate audio URL and metadata

We will make use of the pafy module of python. Not only can this be used for audio, but video as well. Additionally it also gives us the metadata from the URL of the video, like name of video and author.

We will extract the music name, author and the thumbnail for our music player. We will pass the data to a JS function which will populate the front-end. This function will be called from main.js.

# main.py# function to generate URL
@eel.expose
def generate_url(url):
import pafy
music = pafy.new(url)
best = music.getbestaudio()
metaData = {
'title' : music.title,
'author': music.author,
'thumb' : music.thumb
}
url = best.url
eel.music_url(url, metaData)

HTML\CSS\JS Code

To get a rough sketch of the front-end, I designed a simple box design using paint 3d and used that for reference.

musicNet\web\main.html

<!DOCTYPE html><html lang="en">
<head>
<title>musicNet</title>
<!-- Meta Data -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Sanskar Biswal">

<!-- CSS -->
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Scripts -->
<script type="text/javascript" src="/eel.js"></script>
<script type="text/javascript" src="js/main.js"></script
</head>
<body>
<!-- Nav Bar -->
<div class="w3-bar w3-white">
<div class="w3-bar-item">
<img class="w3-image label-image" src="img/lab1.png
</div>
<div class="w3-bar-item w3-right">
<button class="w3-button w3-circle">
<i class="fa fa-user-circle-o fa-lg" aria-hidden="true"></i>
</button>
</div>
</div>
<!-- URL Input Bar -->
<div class="w3-conatiner w3-border URLbar w3-card-4 w3-text-white w3-round-xlarge">
<div class="w3-form w3-row">
<input id="t_URL" type="text" required placeholder="URL Link" class="w3-round-xlarge w3-input w3-twothird">
<div class="w3-row w3-third">
<div class="w3-half">
<button id="t_playlist" class="w3-button w3-bar w3-round-xlarge" onclick="playFromURL()">play</button>
</div>
<div class="w3-half">
<button id="t_playlist" type="submit" class="w3-button w3-bar w3-round-xlarge">playList</button>
</div>
</div>
</div>
</div>
<br><br>
<!-- User Control Panel -->
<div class="w3-container w3-card-4 w3-margin w3-round-xlarge">
<div class="w3-bar w3-large w3-center w3-padding w3-text-white">DASHBOARD
</div>
<div class="w3-row">
<!-- Display Playlists -->
<div class="w3-padding"></div>
<!-- Display Songs in Playlists -->
</div>
</div>
<br><br>
<!-- Player -->
<div class="w3-container w3-card-4 w3-margin w3-round-xlarge">
<div class="w3-row">
<!-- Thumbnail Section -->
<div class="w3-quarter w3-center">
<div class="w3-padding">
<img id="thumb_img" src="img/logo.PNG" class="w3-image">
</div>
</div>
<!-- Player Section -->
<div class="w3-threequarter w3-center player w3-text-white">
<div class="w3-margin-top">
<audio id="audSrc" controls>
<source src="">
</audio>
</div>
<div id="music_name" class="w3-bar w3-text"></div>
</div>
</div>
</div>
<!-- Footer -->
<div class="w3-bar w3-bottom w3-center w3-white">
<div class="w3-padding-16 w3-center">Developed by Sanskar Biswal</div>
</div>
</body>
</html>

musicNet\web\css\main.css

html,body{
background: #666666;
}
.label-image{
height: 50px;
width: auto;
}
.URLbar{
margin-top: 15vh;
margin-left: 10vw;
width: 80%;
}
.player{
height: 15vh
}
.w3-card-4{
background: #212121;
}

musicNet\web\js\main.js

// Local JS Function
function playFromURL(){
// Get URL from User
url = document.getElementById('t_URL').value;
console.log(url);
eel.generate_url(url);
//eel.test();
}
// EEL Exposed Functions
eel.expose(music_url);
function music_url(url, metaData){
// Update Meta Data
document.getElementById('thumb_img').src=metaData.thumb;
document.getElementById('music_name').innerHTML=metaData.title;
// Start Music
document.getElementById('audSrc').setAttribute('src', url);
}

Once all, coding is completed, go to the terminal and run the app.

(venv) $ python main.py

Testing

I am going to the following music for the test

https://www.youtube.com/watch?v=tl0-07dArMs&t=5303s
Paste the URL and press play
The Music Appears in the Player

Coming in Part-II

In the next part we will extend this project for

  • creating a user profile
  • add playlists so that we will not need to search for audio files URL over and over again.
  • we will establish a proper profile and playlist handling system
  • finally, we will package the finished app into a windows program using PyInstaller module

References:

--

--

Sanskar Biswal
TheTeamMavericks

Electronics Engineer | Firmware Developer | Programmer | Poet | Writer