Skip to content

Commit

Permalink
#81
Browse files Browse the repository at this point in the history
  • Loading branch information
kaangiray26 committed Feb 26, 2023
1 parent b738857 commit 8c37716
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 76 deletions.
24 changes: 19 additions & 5 deletions client/src/components/Player.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
<div class="d-flex flex-column">
<div v-show="store.playing.loaded">
<div class="d-flex flex-row justify-content-between align-items-center p-2 pb-0 rounded m-0">
<div class="d-flex flex-row align-items-center clickable" @click="openAlbum">
<img class="img-fluid me-2" :src="get_cover(store.playing.cover)" width="56" height="56" />
<div class="d-flex flex-row align-items-center">
<div class="clickable-shadow" @click="openAlbum">
<img class="img-fluid me-2" :src="get_cover(store.playing.cover)" width="56" height="56" />
</div>
<div class="d-flex flex-column">
<span class="fw-bold text-wrap clickable red-on-hover">{{
store.playing.title
}}</span>
<span class="fw-bold text-wrap clickable red-on-hover mb-1" @click="openAlbum">
{{ store.playing.title }}
</span>
<div>
<button class="btn btn-sm btn-light fw-bold" @click="openQuality">{{
store.playing.quality }}</button>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -113,6 +119,7 @@
:play_previous="play_previous" :repeat_icon="repeat_icon" @queue="show_queue" @lyrics="show_lyrics"
@shuffle="shuffle" @group_session="group_session" />
<GroupSession ref="groupSession" :key="group_key" />
<QualityDisplay ref="qualityDisplay" />
</template>

<script setup>
Expand All @@ -126,6 +133,7 @@ import Queue from './Queue.vue';
import Lyrics from './Lyrics.vue';
import MobileView from './MobileView.vue';
import { action } from '/js/events.js';
import QualityDisplay from './QualityDisplay.vue';
const router = useRouter();
Expand All @@ -142,6 +150,8 @@ const volumeTooltip = ref(null);
const groupSession = ref(null);
const group_key = ref(0);
const qualityDisplay = ref(null);
function get_cover(cover) {
if (cover) {
return cover;
Expand Down Expand Up @@ -329,6 +339,10 @@ async function group_session() {
groupSession.value.show();
}
async function openQuality() {
qualityDisplay.value.show();
}
defineExpose({
show_queue,
show_lyrics,
Expand Down
57 changes: 57 additions & 0 deletions client/src/components/QualityDisplay.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<div id="qualityDisplay" class="modal fade p-2" tabindex="-1">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header d-flex flex-column">
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button>
<h2 class="modal-title fw-bolder">Audio</h2>
</div>
<div class="modal-body">
<ul class="list-group">
<li class="list-group-item">
<span class="fw-bold">Quality: </span>
<span>{{ store.playing.quality }}</span>
</li>
<li class="list-group-item">
<span class="fw-bold">Bitrate: </span>
<span>{{ store.playing.bitrate }} kbps</span>
</li>
<li class="list-group-item">
<span class="fw-bold">Duration: </span>
<span>{{ store.playing.duration }} seconds</span>
</li>
<li class="list-group-item">
<span class="fw-bold">Audio Format: </span>
<span>{{ store.playing.format }}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { Modal } from 'bootstrap';
import { store } from '/js/store.js';
const modal = ref(null);
function _show() {
modal.value.show();
}
function _hide() {
modal.value.hide();
}
defineExpose({
show: _show,
hide: _hide
});
onMounted(() => {
modal.value = new Modal(document.querySelector('#qualityDisplay'));
});
</script>
31 changes: 30 additions & 1 deletion client/src/js/ft.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Forte {
this.track = null;
this.player = new Howl({
src: [null],
format: ['flac'],
format: ['flac', 'mp3', 'ogg', 'wav', 'aac', 'm4a', 'opus', 'webm'],
preload: true,
html5: true,
volume: 1,
Expand All @@ -23,6 +23,7 @@ class Forte {
this.player.on('load', () => {
this.track_loaded()
this.listen_progress()
this.track_quality()
});

this.player.on('end', () => {
Expand Down Expand Up @@ -240,6 +241,34 @@ class Forte {
});
}

async track_quality() {
fetch(this.server + `/api/stream/${store.playing.id}`, {
method: "HEAD",
credentials: "include"
}).then((response) => {
let length = response.headers.get("content-length");
let duration = store.playing.duration;
let kbit = (length * 8) / 1000;

store.playing.format = response.headers.get("content-type");;
store.playing.bitrate = Math.round(kbit / duration);;

if (store.playing.bitrate <= 160) {
store.playing.quality = "LQ";
return;
}
if (store.playing.bitrate <= 320) {
store.playing.quality = "SQ";
return;
}
if (store.playing.bitrate <= 1411) {
store.playing.quality = "HQ";
return;
}
store.playing.quality = "Hi-Res";
})
}

async track_finished() {
let queue = this.getCurrentQueue();
let track = queue[store.queue_index].id;
Expand Down
3 changes: 3 additions & 0 deletions client/src/js/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const store = reactive({
duration: 0,
progress: 0,
radio: false,
bitrate: 0,
format: null,
quality: 'LQ',
},
queue: [],
queue_index: 0,
Expand Down
154 changes: 84 additions & 70 deletions server/js/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,77 @@ const pgp = pgPromise();
const db = pgp('postgres://forte:forte@postgres:5432/forte');
const library_path = '/library';

const exports = {
add_friend: _add_friend,
add_history: _add_history,
add_track_to_playlist: _add_track_to_playlist,
add_user: _add_user,
admin_login: _admin_login,
admin_session: _admin_session,
auth: _auth,
check_friends: _check_friends,
create_playlist: _create_playlist,
delete_playlist: _delete_playlist,
delete_track_to_playlist: _delete_track_to_playlist,
get_album: _get_album,
get_album_loved: _get_album_loved,
get_album_tracks: _get_album_tracks,
get_all_albums: _get_all_albums,
get_artist: _get_artist,
get_artist_loved: _get_artist_loved,
get_config: _get_config,
get_friends: _get_friends,
get_history: _get_history,
get_lyrics: _get_lyrics,
get_playlist: _get_playlist,
get_playlist_loved: _get_playlist_loved,
get_playlist_tracks: _get_playlist_tracks,
get_profile: _get_profile,
get_profile_albums: _get_profile_albums,
get_profile_artists: _get_profile_artists,
get_profile_playlists: _get_profile_playlists,
get_profile_tracks: _get_profile_tracks,
get_random_track: _get_random_track,
get_random_tracks: _get_random_tracks,
get_track: _get_track,
get_track_basic: _get_track_basic,
get_track_loved: _get_track_loved,
get_user: _get_user,
get_user_albums: _get_user_albums,
get_user_artists: _get_user_artists,
get_user_friends: _get_user_friends,
get_user_history: _get_user_history,
get_user_playlists: _get_user_playlists,
get_user_tracks: _get_user_tracks,
get_users: _get_users,
init: _init,
is_authenticated: _is_authenticated,
lastfm_auth: _lastfm_auth,
get_lastfm_auth: _get_lastfm_auth,
lastfm_scrobble: _lastfm_scrobble,
get_lastfm_profile: _get_lastfm_profile,
love_album: _love_album,
love_artist: _love_artist,
love_track: _love_track,
remove_friend: _remove_friend,
remove_user: _remove_user,
search: _search,
search_album: _search_album,
search_artist: _search_artist,
search_track: _search_track,
session: _session,
stream: _stream,
stream_head: _stream_head,
unlove_album: _unlove_album,
unlove_artist: _unlove_artist,
unlove_track: _unlove_track,
update_album: _update_album,
update_artist: _update_artist,
update_config: _update_config,
update_track: _update_track,
upload_cover: _upload_cover,
}

async function _init(args) {
if (args.includes('--reset')) {
let answer = readlineSync.question("Do you really want to reset? (y/n)");
Expand Down Expand Up @@ -373,6 +444,19 @@ async function _stream(req, res, next) {
})
}

async function _stream_head(req, res, next) {
let id = req.params.id;
if (!id) {
res.status(400).json({ "error": "ID parameter not given." });
return;
}
db.oneOrNone("SELECT path FROM tracks WHERE id = $1", [id])
.then(function (data) {
res.status(200)
.sendFile(data.path, { headers: { 'Content-Type': true, 'Content-Length': true } })
})
}

async function _get_artist(req, res, next) {
let id = req.params.id;
if (!id) {
Expand Down Expand Up @@ -1693,74 +1777,4 @@ function get_api_sig(obj, sig) {
return crypto.createHash('md5').update(str).digest("hex");
}

const exports = {
add_friend: _add_friend,
add_history: _add_history,
add_track_to_playlist: _add_track_to_playlist,
add_user: _add_user,
admin_login: _admin_login,
admin_session: _admin_session,
auth: _auth,
check_friends: _check_friends,
create_playlist: _create_playlist,
delete_playlist: _delete_playlist,
delete_track_to_playlist: _delete_track_to_playlist,
get_album: _get_album,
get_album_loved: _get_album_loved,
get_album_tracks: _get_album_tracks,
get_all_albums: _get_all_albums,
get_artist: _get_artist,
get_artist_loved: _get_artist_loved,
get_config: _get_config,
get_friends: _get_friends,
get_history: _get_history,
get_lyrics: _get_lyrics,
get_playlist: _get_playlist,
get_playlist_loved: _get_playlist_loved,
get_playlist_tracks: _get_playlist_tracks,
get_profile: _get_profile,
get_profile_albums: _get_profile_albums,
get_profile_artists: _get_profile_artists,
get_profile_playlists: _get_profile_playlists,
get_profile_tracks: _get_profile_tracks,
get_random_track: _get_random_track,
get_random_tracks: _get_random_tracks,
get_track: _get_track,
get_track_basic: _get_track_basic,
get_track_loved: _get_track_loved,
get_user: _get_user,
get_user_albums: _get_user_albums,
get_user_artists: _get_user_artists,
get_user_friends: _get_user_friends,
get_user_history: _get_user_history,
get_user_playlists: _get_user_playlists,
get_user_tracks: _get_user_tracks,
get_users: _get_users,
init: _init,
is_authenticated: _is_authenticated,
lastfm_auth: _lastfm_auth,
get_lastfm_auth: _get_lastfm_auth,
lastfm_scrobble: _lastfm_scrobble,
get_lastfm_profile: _get_lastfm_profile,
love_album: _love_album,
love_artist: _love_artist,
love_track: _love_track,
remove_friend: _remove_friend,
remove_user: _remove_user,
search: _search,
search_album: _search_album,
search_artist: _search_artist,
search_track: _search_track,
session: _session,
stream: _stream,
unlove_album: _unlove_album,
unlove_artist: _unlove_artist,
unlove_track: _unlove_track,
update_album: _update_album,
update_artist: _update_artist,
update_config: _update_config,
update_track: _update_track,
upload_cover: _upload_cover,
}

export default exports
1 change: 1 addition & 0 deletions server/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ app.post("/api/cover", isAuthenticated, upload.single('cover'), db.upload_cover)

app.get("/api/search/:query", isAuthenticated, db.search)
app.get("/api/stream/:id", isAuthenticated, db.stream)
app.head("/api/stream/:id", isAuthenticated, db.stream_head)

app.get("/api/profile/", isAuthenticated, db.get_profile)
app.get("/api/profile/history", isAuthenticated, db.get_history)
Expand Down

0 comments on commit 8c37716

Please sign in to comment.