Skip to content

Commit

Permalink
Created music-api
Browse files Browse the repository at this point in the history
Created a music-api #95
  • Loading branch information
its-kritika committed May 17, 2024
1 parent 4fad3a1 commit 09a623f
Show file tree
Hide file tree
Showing 11 changed files with 1,232 additions and 0 deletions.
870 changes: 870 additions & 0 deletions New_APIs/music-api/package-lock.json

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions New_APIs/music-api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "music-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node src/app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^16.4.5",
"express": "^4.19.2",
"spotify-web-api-node": "^5.0.2"
}
}
76 changes: 76 additions & 0 deletions New_APIs/music-api/public/css/search.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
body{
box-sizing: border-box;
background-image: url('../img/search-background1.jpg');
background-size: cover;
background-repeat: no-repeat;
background-position: 0 -50px;
/* backdrop-filter: contrast(50%) brightness(80%); */
margin: 0;
height: 88vh;
}
.enterp{
text-align: left;
color: white;
padding-left: 8%;
}
.search-container{
font-family: Arial, Helvetica, sans-serif;
width: 60%;
margin: 3% auto;
text-align: center;
padding: 5% 6%;
backdrop-filter: blur(3px) contrast(50%) brightness(70%);
height: 77%;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
.msg-box{
width: 55%;
margin: 3% auto;
backdrop-filter: blur(3px);
color: white;
}
input{
width: 40vw;
height: 7vh;
margin: 0 5% 2% 0;
font-size: 17px;
text-indent: 10px;
outline: none;
border: none;
background-color: rgb(238, 236, 236);
}
button{
height: 7vh;
width: 7rem;
cursor: pointer;
background-color: rgb(81, 133, 231);
border: none;
color: white;
font-size: 17px;
}
img{
height: 200px;
width: 220px;
object-fit: cover;
}
.hidden{
display: none;
}
.flex {
display: flex;
}
.first-para{
margin-bottom: 0;
width: 66%;
text-align: right;
}
.icon{
margin-top: 6px;
margin-left: 15px;
height: 18px;
width: 32px;
border: 1px solid;
padding: 7px 0;
border-radius: 50%;
color: white;
}
29 changes: 29 additions & 0 deletions New_APIs/music-api/public/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
body{
box-sizing: border-box;
background-color: rgb(200, 200, 200);
}
.login-container{
width: 40%;
height: 200px;
margin: auto;
background-color: rgb(97, 149, 245);
font-family: Arial, Helvetica, sans-serif;
padding: 6%;
color: rgb(38, 38, 38);
text-align: center;
margin-top: 8%;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
.login-container button{
width: 110px;
height: 45px;
cursor: pointer;
margin-top: 35px;
font-size: 16px;
border: none;
}
.login-container button:hover{
color: rgb(54, 121, 245);
text-decoration: underline;
font-weight: bold;
}
Binary file added New_APIs/music-api/public/img/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions New_APIs/music-api/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Music API</title>
<link rel ="stylesheet" href = "/css/style.css">
<link rel = 'icon' href="/img/favicon.png">
</head>
<body>
<div class = 'login-container'>
<p class = 'loginp'>Welcome to the music app! <br><br>Login with your Spotify account to continue!</p>
<a href = '/login'><button>Login</button></a>
</div>
</body>
</html>
81 changes: 81 additions & 0 deletions New_APIs/music-api/public/js/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const searchForm = document.querySelector('form')
const searchItem = document.querySelector('input')

const messageOne = document.querySelector('#message-1')
const messageTwo = document.querySelector('#message-2')
const messageThree = document.querySelector('#message-3')
const messageFour = document.querySelector('#message-4')
const messageFive = document.querySelector('#message-5')
const messageSong = document.querySelector('#song-image')
const play = document.querySelector('#icon')
let songUri = ''

searchForm.addEventListener('submit', (e) => {
//set this to prevent browser from refreshing on form submission
e.preventDefault()

const song = searchItem.value
messageOne.textContent = 'Loading...'
messageTwo.textContent = ''
messageThree.textContent = ''
messageFour.textContent = ''
messageFive.textContent = ''
messageSong.classList.add('hidden')
play.classList.add('hidden')

fetch('/search?q='+song).then((response) => {
response.json().then((data) => {
if (data.error){
messageOne.classList.remove('first-para')
messageOne.textContent = data.error
}
else{
messageOne.classList.add('first-para')
messageOne.textContent = 'Your song is : '+data.name
play.classList.remove('hidden')
sungByMsg = ''
artist = data.artists

for (i = 0; i < artist.length; i++ ){
sungByMsg += artist[i].name
if (i < artist.length-1)
sungByMsg += ', '
}
messageTwo.textContent = 'Movie Name : '+data.album.name
messageThree.textContent = 'Song by : '+ sungByMsg
messageFour.textContent = 'Composed by : '+data.album.artists[0].name
messageFive.textContent = 'Duration : '+ formatDuration(data.duration_ms)
messageSong.src = data.album.images[0].url
messageSong.classList.remove('hidden')

//Store song uri
songUri = data.uri
}
})
})
})

function formatDuration(milliseconds) {
// Convert milliseconds to seconds
const totalSeconds = Math.floor(milliseconds / 1000);

// Calculate minutes and seconds
const minutes = Math.floor(totalSeconds / 60)
const seconds = totalSeconds % 60

// Construct the formatted string
var formattedDuration = ''
if (minutes > 0) {
formattedDuration += minutes + 'min '
}
if (seconds > 0) {
formattedDuration += seconds + 'sec'
}

return formattedDuration.trim()
}

play.addEventListener('click', (e) => {
e.preventDefault() // Prevent default button behavior
window.location.href = '/play?uri=' + encodeURIComponent(songUri)
})
11 changes: 11 additions & 0 deletions New_APIs/music-api/public/play.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Music API</title>
<link rel = 'icon' href="/img/favicon.png">

</head>
<body>
<p>Playback started! Enjoy!!!! 😃</p>
</body>
</html>
37 changes: 37 additions & 0 deletions New_APIs/music-api/public/search.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Music API</title>
<link rel ="stylesheet" href = "/css/search.css">
<link rel = 'icon' href="/img/favicon.png">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
crossorigin="anonymous" referrerpolicy="no-referrer" /> <!--for font awesome icons-->

</head>
<body>
<div class = 'search-container'>
<p class = 'enterp'>Enter song to search:</p>
<form>
<input placeholder="Search a song">
<button>Search</button>
</form>
<div class="msg-box">
<img id = 'song-image' src = '' alt = 'song-image' class = 'hidden'>
<div id = 'flex' class="flex">
<p id = 'message-1' class="first-para"></p>
<a href = '' class = 'hidden icon' id = 'icon'>
<i class="fa-solid fa-play"></i>
</a>
</div>
<p id = 'message-2'></p>
<p id = 'message-3'></p>
<p id = 'message-4'></p>
<p id = 'message-5'></p>
</div>
</div>

<script src = '/js/script.js'></script>
</body>
</html>
97 changes: 97 additions & 0 deletions New_APIs/music-api/src/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require('dotenv').config()
const path = require('path')
const express = require('express')
const SpotifyWebApi = require('spotify-web-api-node');

const spotifyApi = new SpotifyWebApi({
clientId: process.env.CLIENT_ID ,
clientSecret: process.env.CLIENT_SECRET,
redirectUri: process.env.REDIRECT_URL
});

const app = express()

const publicDirectoryName = path.join(__dirname, '../public')

app.use(express.static(publicDirectoryName))

app.get('/login', (req, res) => {

const scope = ['user-read-private', 'user-read-email', 'user-read-playback-state', 'user-modify-playback-state'];
res.redirect(spotifyApi.createAuthorizeURL(scope));
});

app.get('/callback', (req, res) => {
const error = req.query.error
const code = req.query.code
const state = req.query.state

if (error){
return res.send(`Error : ${error}`)
}

spotifyApi.authorizationCodeGrant(code).then((data) => {
const accessToken = data.body['access_token']
const refreshToken = data.body['refresh_token']
const expiresIn = data.body['expires_in']

spotifyApi.setAccessToken(accessToken)
spotifyApi.setRefreshToken(refreshToken)

res.sendFile(path.join(__dirname, '../public', 'search.html'));

setInterval(async () => {
const data = await spotifyApi.refreshAccessToken()
const accessTokenRefreshed = data.body['access_token']

spotifyApi.setAccessToken(accessTokenRefreshed)
}, expiresIn/2*1000)
}).catch((error) => {
return res.send({
error : error.body.error_description,
solution : 'Session has expired! Login Again to continue!!'
})
})
});


app.get('/search', (req, res) => {
const {q} = req.query
spotifyApi.searchTracks(q).then((searchData) => {
const trackUri = searchData.body.tracks.items[0]
res.send(trackUri)
}).catch((error) => {
res.send({
error : 'Sorry! We could not find a match. Try another search and if issue persists, login again to continue!'
})
})
})


app.get('/play', (req, res) => {
const { uri } = req.query
spotifyApi.play({uris : [uri]}).then(() => {
res.sendFile(path.join(__dirname, '../public', 'play.html'));

}).catch((error) => {
res.send(`Error in playing song : ${error}`)
})
})

app.get('/help' , (req, res) => {
res.send({
message : 'This Page is built to help you with the functionalities of app!🙂',
title : 'Help Section'
})
})

app.get('*',(req, res) => {
res.send({
title: '404 Page',
message: 'Page could not be found!'
})
})

app.listen(3000, () => {
console.log('Server has started functioning!')
})

0 comments on commit 09a623f

Please sign in to comment.