Skip to content

Commit

Permalink
feat: huge feature: a floating player, with a movable playhead
Browse files Browse the repository at this point in the history
  • Loading branch information
TerryGeng committed May 17, 2020
1 parent b050546 commit 0b7d0b8
Show file tree
Hide file tree
Showing 9 changed files with 341 additions and 35 deletions.
20 changes: 16 additions & 4 deletions database.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def order_by(self, order_by, desc=False):


SETTING_DB_VERSION = 2
MUSIC_DB_VERSION = 2
MUSIC_DB_VERSION = 3


class SettingsDatabase:
Expand Down Expand Up @@ -503,7 +503,8 @@ def __init__(self, settings_db: SettingsDatabase, music_db: MusicDatabase):
self.settings_table_migrate_func = {0: self.settings_table_migrate_from_0_to_1,
1: self.settings_table_migrate_from_1_to_2}
self.music_table_migrate_func = {0: self.music_table_migrate_from_0_to_1,
1: self.music_table_migrate_from_1_to_2}
1: self.music_table_migrate_from_1_to_2,
2: self.music_table_migrate_from_2_to_3}

def migrate(self):
self.settings_database_migrate()
Expand Down Expand Up @@ -564,7 +565,7 @@ def music_database_migrate(self):

else:
log.info(f"database: no music table found. Creating music table version {MUSIC_DB_VERSION}.")
self.create_music_table_version_2(conn)
self.create_music_table_version_3(conn)

conn.commit()
conn.close()
Expand Down Expand Up @@ -607,7 +608,7 @@ def create_music_table_version_1(self, conn):

conn.commit()

def create_music_table_version_2(self, conn):
def create_music_table_version_3(self, conn):
self.create_music_table_version_1(conn)

def settings_table_migrate_from_0_to_1(self, conn):
Expand Down Expand Up @@ -669,3 +670,14 @@ def music_table_migrate_from_1_to_2(self, conn):
conn.commit()

return 2 # return new version number

def music_table_migrate_from_2_to_3(self, conn):
items_to_update = self.music_db.query_music(Condition(), conn)
for item in items_to_update:
if 'duration' not in item:
item['duration'] = 0

self.music_db.insert_music(item)
conn.commit()

return 3 # return new version number
17 changes: 15 additions & 2 deletions interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,19 @@ def playlist():
title = item.format_title()
artist = "??"
path = ""
duration = 0
if isinstance(item, FileItem):
path = item.path
if item.artist:
artist = item.artist
duration = item.duration
elif isinstance(item, URLItem):
path = f" <a href=\"{item.url}\"><i>{item.url}</i></a>"
duration = item.duration
elif isinstance(item, PlaylistURLItem):
path = f" <a href=\"{item.url}\"><i>{item.url}</i></a>"
artist = f" <a href=\"{item.playlist_url}\"><i>{item.playlist_title}</i></a>"
duration = item.duration
elif isinstance(item, RadioItem):
path = f" <a href=\"{item.url}\"><i>{item.url}</i></a>"

Expand All @@ -223,6 +227,7 @@ def playlist():
'artist': artist,
'thumbnail': thumb,
'tags': tag_tuples,
'duration': duration
})

return jsonify({
Expand All @@ -240,15 +245,19 @@ def status():
'empty': False,
'play': not var.bot.is_pause,
'mode': var.playlist.mode,
'volume': var.bot.volume_set})
'volume': var.bot.volume_set,
'playhead': var.bot.playhead
})

else:
return jsonify({'ver': var.playlist.version,
'current_index': var.playlist.current_index,
'empty': True,
'play': not var.bot.is_pause,
'mode': var.playlist.mode,
'volume': var.bot.volume_set})
'volume': var.bot.volume_set,
'playhead': 0
})


@web.route("/post", methods=['POST'])
Expand Down Expand Up @@ -335,6 +344,10 @@ def post():
if len(var.playlist) >= int(request.form['play_music']):
var.bot.play(int(request.form['play_music']))
time.sleep(0.1)
elif 'move_playhead' in request.form:
if float(request.form['move_playhead']) < var.playlist.current_item().item().duration:
log.info(f"web: move playhead to {float(request.form['move_playhead'])} s.")
var.bot.play(var.playlist.current_index, float(request.form['move_playhead']))

elif 'delete_item_from_library' in request.form:
_id = request.form['delete_item_from_library']
Expand Down
9 changes: 7 additions & 2 deletions media/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import mutagen
from PIL import Image

import util
import variables as var
from media.item import BaseItem, item_builders, item_loaders, item_id_generators, ValidationFailedError
import constants
Expand Down Expand Up @@ -51,6 +52,7 @@ def __init__(self, path, from_dict=None):
if os.path.exists(self.uri()):
self._get_info_from_tag()
self.ready = "yes"
self.duration = util.get_media_duration(self.uri())
self.keywords = self.title + " " + self.artist
else:
super().__init__(from_dict)
Expand All @@ -75,7 +77,9 @@ def validate(self):
"file: music file missed for %s" % self.format_debug_string())
raise ValidationFailedError(constants.strings('file_missed', file=self.path))

# self.version += 1 # 0 -> 1, notify the wrapper to save me when validate() is visited the first time
if self.duration == 0:
self.duration = util.get_media_duration(self.uri())
self.version += 1 # 0 -> 1, notify the wrapper to save me
self.ready = "yes"
return True

Expand Down Expand Up @@ -130,7 +134,8 @@ def _get_info_from_tag(self):
if not self.title:
self.title = os.path.basename(file_no_ext)

def _prepare_thumbnail(self, im):
@staticmethod
def _prepare_thumbnail(im):
im.thumbnail((100, 100), Image.ANTIALIAS)
buffer = BytesIO()
im = im.convert('RGB')
Expand Down
5 changes: 4 additions & 1 deletion media/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __init__(self, from_dict=None):
self.path = ""
self.tags = []
self.keywords = ""
self.duration = 0
self.version = 0 # if version increase, wrapper will re-save this item

if from_dict is None:
Expand All @@ -62,6 +63,7 @@ def __init__(self, from_dict=None):
self.title = from_dict['title']
self.path = from_dict['path']
self.keywords = from_dict['keywords']
self.duration = from_dict['duration']

def is_ready(self):
return True if self.ready == "yes" else False
Expand Down Expand Up @@ -117,4 +119,5 @@ def to_dict(self):
"title": self.title,
"path": self.path,
"tags": self.tags,
"keywords": self.keywords}
"keywords": self.keywords,
"duration": self.duration}
2 changes: 1 addition & 1 deletion static/css/bootstrap.min.css

Large diffs are not rendered by default.

70 changes: 67 additions & 3 deletions static/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
font-weight: 300;
}

/* Theme changer */
/* Theme changer and player button */
.floating-button {
width: 50px;
height: 50px;
Expand All @@ -100,7 +100,6 @@
line-height: 52px;
position: fixed;
right: 50px;
bottom: 40px;
}
.floating-button:hover {
background-color: hsl(0, 0%, 43%);
Expand All @@ -122,7 +121,6 @@
font-size: 20px;
border-radius: 4px;
display: none;
/* margin-bottom: 5px; */
}
#volume-popover[data-show] {
display: flex;
Expand All @@ -148,3 +146,69 @@
#volume-popover[data-popper-placement^='top'] > #volume-popover-arrow {
bottom: -4px;
}
#playerToast {
position: fixed;
right: 20px;
top: 20px;
max-width: 800px;
}
#playerContainer {
display: flex;
height: 105px;
}
#playerArtwork {
width: 80px;
height: 80px;
border-radius: 5px;
}
#playerArtworkIdle {
width: 80px;
height: 80px;
border-radius: 5px;
margin: auto;
padding: 15px;
}
#playerInfo {
position: relative;
padding-top: 6px;
margin-left: 10px;
height: 80px;
font-size: 15px;
}
#playerTitle {
display: block;
white-space: nowrap;
}
#playerArtist {
display: block;
white-space: nowrap;
min-height: 20px;
}
#playerActionBox {
margin-top: 5px;
display: flex;
float: right;
}
#playerBarBox {
margin-top: 5px;
height: 15px;
width: 400px;
cursor: pointer;
}
.scrolling {
animation: scrolling 8s linear infinite;
}
@keyframes scrolling {
0% {
transform: translateX(100%);
opacity: 1;
}
95%{
transform: translateX(-90%);
opacity: 1;
}
100% {
transform: translateX(-100%);
opacity: 0;
}
}

0 comments on commit 0b7d0b8

Please sign in to comment.