How to create a Music Player application using Django

In this Python Django tutorial, we will learn How to create a Music Player using Python Django. We will create this Python Django Music player with a song list where we can add and remove songs using the Django database.

We will build this Django music player with models, forms, and templates in Python using Django, Javascript, and Bootstrap. We can create a complete playlist of our songs in our Python Django music player.

Django Music Player application
Python Django Music Player application

How to create a music player application using Django?

To create a music player application in Python Django we need the basic configurations of a Django project. In this project, we are going to discuss the points mentioned below in the further steps.

  • Set up a Python Django project with basic configurations.
  • Create HTML templates for the structure of our Python Django application.
  • Using Bootstrap through a CDN link.
  • Create static Javascript files and CSS files.
  • Create views using the Paginator class, we will discuss the pagination function in further steps.
  • Add songs to our Django music player using the default dbsqlite3 database.

Step 1: Setup a Python Django Project

Firstly, to set up our Python Django project we will create a virtual environment, and after creating it we will activate the virtual environment in our project directory.

To set up a virtual environment, create a new folder in which you have to set up your Django Project and open that folder in vs code and run the below command.

python -m venv musicenv

Now the virtual environment is being created in our Python Django project, to activate it follow the below command.

musicenv\Scripts\activate

Create Django Project and application

To create a project run the below command in the terminal. It will create some default Python directories for the Python Django project.

django-admin startproject DjangoMusicPlayer

Now we have created a project so, we need to move inside the Python Django project directory to work on our project. We will use the below line of command for that.

cd DjangoMusicPlayer

After this, we will create an app using the below command.

python manage.py startapp musicapp

Register app

To register the musicapp go to the settings.py section and under the INSTALLED APP section register the app using the below code.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'musicapp',
]

Step 2: Creating templates and Static files

Create two folders named templates and static and in the templates folder create an HTML file index.html and follow the below code in the index.html file. A picture is shown below to understand the structure of files.

Python Django Music Player
templates and static files in Django music app
{% load static %}

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8"/>
  <title>
   Django Music Player
  </title>
  <link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"/>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.7/mediaelementplayer.min.css" rel="stylesheet"/>
  <link href="{% static './style.css' %}" rel="stylesheet"/>
 </head>
 <body>
  
  <!-- <html>
   <head>
    <meta charset="utf-8"/>
    <title>
     Django music player
    </title>
   </head>
   <body> -->
    <div class="contain">
     <div class="container">
      <div class="music-player">
        {% for item in page_obj %}
       <div class="cover">
        <img alt="" src="{{item.image.url}}"/>
       </div>
       <div class="titre">
        <h3>
         {{item.artist}}
        </h3>
        <h1>
         {{item.title}}
        </h1>
       </div>
       <center><a href="{% if page_obj.has_previous %}?page={{ page_obj.previous_page_number }}{% endif %}"><i class="fa fa-step-backward fa-2x"></i></a> &nbsp; &nbsp; &nbsp; <a href="{% if page_obj.has_next %}?page={{ page_obj.next_page_number }} {% endif %}"><i class="fa fa-step-forward fa-2x"></i></a></center>
       <div class="lecteur">
        <audio class="fc-media" style="width: 100%;">
         <source src="{% if item.audio_file %}{{item.audio_file.url}} {% else %} {{item.audio_link}} {% endif %}" type="audio/mp3"/>
        </audio>

       </div>
       {% endfor %}
      </div>
     </div>
    </div>
   </body>
  </html>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js">
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.7/mediaelement-and-player.min.js">
  </script>
  <script src="{% static './script.js' %}">
  </script>
 </body>
</html>

In our index.html file, we have Bootstrap using a CDN link. We have also used page_obj context which will render our query set object in the template. We will use and define the “page_obj” in our views.py later.

Create static files script.js and style.css in the static folder

Now in the Static folder create a javascript file script.js and follow the below code in static.js

var audio = {    
    init: function() {        
    var $that = this;        
        $(function() {            
            $that.components.media();        
        });    
    },
    components: {        
        media: function(target) {            
            var media = $('audio.fc-media', (target !== undefined) ? target : 'body');            
            if (media.length) {                
                media.mediaelementplayer({                    
                    audioHeight: 40,
                    features : ['playpause', 'current', 'duration', 'progress', 'volume', 'tracks', 'fullscreen'],
                    alwaysShowControls      : true,
                    timeAndDurationSeparator: '<span></span>',
                                 
                });            
            }        
        },
            
    },
};

audio.init();

Now in the Static folder create a javascript file style.css and follow the below code in style.css

$red: #EB2045;
$grey: #0B0B0B;
$p: 12px;
$easeInBack: cubic-bezier(0.600, -0.280, 0.735, 0.045);
$easeOutBack: cubic-bezier(0.175, 0.885, 0.320, 1.275);
$easeOutCubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);

*, *:before, *:after { box-sizing: border-box; }
* { -webkit-tap-highlight-color: rgba(0,0,0,0); transform-style: preserve-3d; }
*:focus { outline: none!important; }
::selection { background: none; }
a { cursor: pointer; }
body, html { height: 100%; }
hr {
	border: 0;
	margin: 0;
	padding: 0;
	width: 100%;
	height: 1px;
	background: rgba($grey, .5);
}

body {
	color: $grey;
	font-family: "Roboto Mono", monospace;
	text-rendering: optimizeLegibility;
	-webkit-font-smoothing: antialiased;
}
main {
	perspective: 1000px;
	transform-style: preserve-3d;
	display: flex;
	justify-content: center;
	align-items: center;
	align-content: center;
	position: relative;
	width: 100%;
	height: 100%;
	padding: $p;
}

.background {
	background: white;
	&, &:before, &:after, div {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
	}
	&:before {
		content: "";
		background: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/345377/thousand-thursday%402x.jpg') center center / cover;
		filter: blur(2px);
	}
	div {
		background: $red;
		mix-blend-mode: screen;
	}
	&:after {
		content: "";
		background: rgba(black, .15);
	}
}

.player {
	position: relative;
	z-index: 3;
	width: 100%;
	max-width: 320px;
	.back {
		opacity: 0;
	}
	&.playlist {
		.front {
			z-index: -1;
			opacity: 0;
		}
		.back {
			z-index: 1;
			opacity: 1;
		}
	}
}
.player, .back, .front {
	will-change: transform;
	transform-origin: center center;
	transform-style: preserve-3d;
	backface-visibility: hidden;
}
.front, .back {
	transition: all 500ms $easeOutBack;
	background: white;
	border-radius: 2px;
	box-shadow: 0 0 15px rgba(mix($red, $grey), .2);
}
.back {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	header {
		display: flex;
		align-items: center;
		align-content: center;
		background: rgba($grey, .1);
		padding: $p;
		a {
			display: block;
			padding: 0 5px 3px!important;
			border-radius: 2px;
			margin-right: $p;
			background: rgba($grey, .1);
		}
	}
	a {
		display: flex;
		padding: $p;
		&:hover, &:focus {
			background: $red;
			color: white;
		}
		&:active {
			background: $grey;
		}
	}
	img {
		display: block;
		border-radius: 2px;
		height: 32px;
		width: 32px;
		+ div {
			padding-left: $p;
		}
	}
	hr {
		margin-left: $p;
		width: calc(100% - #{$p*2});
		background: rgba($grey, .1);
	}
	h3 {
		margin-bottom: 4px;
		font-size: 16px;
		font-weight: 300;
	}
	h4 {
		font-size: 12px;
		font-weight: 500;
	}
}
.art {
	border-radius: 2px 2px 0 0;
	display: block;
	width: 100%;
}
.bar {
	position: relative;
	z-index: 2;
	width: 100%;
	height: $p;
	margin-top: -$p/2;
	overflow: hidden;
	&:before, hr {
		display: block;
		position: absolute;
		top: 50%;
		margin-top: -1px;
		left: 0;
		width: 100%;
		height: 2px;
	}
	&:before {
		content: "";
		background: #bbb;
	}
	hr {
		transform: translateX(-50%);
		margin-bottom: 0;
		padding: 0;
		border: 0;
		background: $red;
		&:after {
			transform-origin: center center;
			content: "";
			display: block;
			position: absolute;
			right: -$p/2;
			top: 50%;
			margin-top: -$p/2;
			width: $p;
			height: $p;
			background: $red;
			border-radius: 2px;
		}
		&:hover {
			background: $grey;
			&:after {
				background: $grey;
			}
		}
	}
}
.controls {
	display: flex;
	align-items: center;
	align-content: center;
	width: 100%;
	a {
		display: block;
		svg {
			display: block;
			width: 100%;
			height: 100%;
		}
		&.skip {
			width: 36px;
			height: 20px;
		}
		&.play {
			width: 42px;
			height: 36px;
		}
	}
	&.top {
		justify-content: space-around;
		padding: $p;
		a {
			transition: all 250ms ease-out;
			will-change: transform;
			svg {
				fill: $grey;
			}
			&:hover, &:focus {
				transition: all 500ms $easeOutBack;
				transform: scale(1.1);
				svg {
					fill: $red;
				}
			}
			&:active {
				transform: scale(1);
			}
		}
	}
	&.bottom {
		justify-content: space-between;
		padding: $p*1.5 $p $p;
		a {
			width: 24px;
			height: 20px;
			svg {
				fill: rgba($red, .25);
			}
			&:hover, &:focus, &.active {
				svg {
					fill: $red;
				}
			}
			&.flip {
				svg {
					fill: rgba($grey, .25);
				}
				&:hover, &:focus {
					svg {
						fill: $grey;
					}
				}
			}
		}
	}
}
.meta {
	text-align: center;
	time {
		display: flex;
		justify-content: space-between;
		width: 100%;
		padding: 0 $p/3;
		font-size: 10px;
	}
	.info {
		padding: $p;
	}
	h1 {
		font-size: 20px;
		font-weight: 300;
		margin-bottom: $p/2;
	}
	h2 {
		font-size: 14px;
		font-weight: 500;
	}
}

.pre-enter {
	.background {
		opacity: 0;
	}
	.player {
		opacity: 0;
		transform-origin: center top;
		will-change: opacity, transform;
		transform: rotateX(30deg) rotateY(-30deg) translateY(300px) translateZ(200px);
	}
}
.on-enter {
	.background {
		transition: all 1000ms ease-out;
		opacity: 1;
	}
	.player {
		animation: rotateIn 1000ms $easeOutCubic 500ms forwards;
	}
}

@keyframes rotateIn {
	0% {
		opacity: 0;
		transform: rotateX(30deg) rotateY(-30deg) translateY(300px) translateZ(200px);
	}
	10% {
		opacity: 1;
	}
	100% {
		opacity: 1;
		transform: none;
	}
}

@media only screen and (max-height: 510px) {
	.container {
		transform-origin: center center;
		transform: scale(0.75);
	}
}

@media only screen and (min-width: 640px) {
	.with-hover {
		.player {
			transition: all 500ms ease-out;
			&:hover {
				transition: all 1000ms $easeOutBack;
			}
		}
	}
	.player {
		will-change: transform;
		&:hover {
			transform: translateZ(#{$p*5});
		}
		.back {
			transform: rotateY(180deg);
			* {
				opacity: 0;
			}
		}
		&.playlist {
			.front {
				transform: rotateY(180deg);
				* {
					opacity: 0;
				}
			}
			.back {
				transform: rotateY(0);
				* {
					opacity: 1;
				}
			}
		}
	}
	.bar {
		hr {
			cursor: col-resize;
		}
	}
}

Registering media and media files in the settings.py file

We need to define our static and media files in the settings.py file. For that import os module in the settings .py file as shown below.

Python Django music player app
Registering media files in Django music app

Now in the settings.py file, we will define static files and media files. For that follow the below code in the settings.py file.

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

Define URL paths in the DjangoMusicPlayer

We will create URLs for the DjangoMusicPlayer by following the below code.

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.contrib.staticfiles.urls import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('musicapp.urls')),

]
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Define URL paths in the musicapp

from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
from . import views

app_name = "App"

urlpatterns = [
    path("", views.index, name="index"),
]

Creating models in the app

To create models go to the models.py file in the musicapp and follow the below code.

# Create your models here.
class Song(models.Model):
    title= models.TextField()
    artist= models.TextField()
    image= models.ImageField()
    audio_file = models.FileField(blank=True,null=True)
    audio_link = models.CharField(max_length=200,blank=True,null=True)
    duration=models.CharField(max_length=20)
    paginate_by = 2

    def __str__(self):
        return self.title

Step 3: Create views using Django Pagination()

Now we will create a view in the views.py file of our application musicapp. We are going to use Pagination to create views. So Pagination uses the Paginator class which takes a list of objects, plus the number of items you’d like to have on each page, and it gives you methods for accessing the items for each page.

Likewise, we have a playlist of songs and each song is for a different page so the Paginator class gives us the method to access all of them and render them on the same page.

Create views in the views.py file using the below code.

# Create your views here.
from django.shortcuts import render, redirect

# imported our models
from django.core.paginator import Paginator
from . models import Song

def index(request):
    paginator= Paginator(Song.objects.all(),1)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    context={"page_obj":page_obj}
    return render(request,"index.html",context)

Make migrations

After creating models we need to make migrations to apply those changes in the database. To make migrations run the below commands in the terminal.

> python manage.py makemigrations
> python manage.py migrate

Step 4: Add Songs through the default sqlite3 Database

In this step, we will view our database through the admin panel and add songs to our music player. Follow the below steps for that.

Create a superuser for the admin panel

To access the admin panel, we first need to create a super user and to create a superuser, follow the below command in the terminal.

python manage.py createsuperuser

Fill in the credentials as shown in the picture below.

Python Django music player
Superuser in Django music player

Run the development server

To run the development server run the command mentioned below.

python manage.py runserver

To view our Music player in the database run the management server with the Python URL link  http://127.0.0.1:8000/ admin it will redirect you to the admin panel.

After entering the login credentials of the superuser which we entered earlier, it will redirect you to the admin panel where you can add songs to the music player through the database.

Python Django music player application
Adding songs in Django Music Player

After adding songs click on save you will see the lists of songs as shown in the picture below.

Music Player in Python Django
Songs listed in Django Music Player

Step 5: Run the development server to view our application

We have completed all the setup requirements of our Django Music Player application. We will view our application through the development server. To run the development server we will again use the runserver command.

>  python manage.py runserver

Now the URL link  http://127.0.0.1:8000/ page will redirect you to the server where we will see our application.

Django Music Player app with Python
Django Music Player App

Conclusion

In this Python Django tutorial, we learned how to create a Music Player app in Django. We created this app through models, templates, and static files and also added Bootstrap to make our application look more dynamic.

We also about Page_obj context and its functionalities and we also got a good understanding of Pagination and Paginator class.

You may like to read: