return jsonify({'ver': var.playlist.version,
'empty': False,
'play': not var.bot.is_pause,
+ 'playhead': var.bot.playhead,
'mode': var.playlist.mode})
else:
return jsonify({'ver': var.playlist.version,
'empty': True,
'play': False,
+ 'playhead': -1,
'mode': var.playlist.mode})
import base64
import hashlib
import mutagen
+import subprocess
from PIL import Image
import variables as var
item_id_generators['file'] = file_item_id_generator
+def get_duration(filename):
+ # use mediainfo if possible
+ p = subprocess.Popen(['mediainfo', '--Inform=Audio;%Duration%', filename],
+ close_fds=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ try:
+ return int(stdout) / 1000
+ except ValueError:
+ pass
+
+ # fallback on soxi
+ p = subprocess.Popen(['soxi', filename], close_fds=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ for line in stdout.splitlines():
+ if not line.startswith('Duration'):
+ continue
+ try:
+ hours, minutes, seconds = re.findall(r'(\d\d):(\d\d):(\d\d)', line)[0]
+ except IndexError:
+ continue
+ return int(hours) * 3600 + int(minutes)*60 + int(seconds)
+ return None
+
+
class FileItem(BaseItem):
def __init__(self, bot, path, from_dict=None):
if not from_dict:
self.title = ""
self.artist = ""
self.thumbnail = None
+ self.duration = None
self.id = hashlib.md5(path.encode()).hexdigest()
if os.path.exists(self.uri()):
self._get_info_from_tag()
self.title = from_dict['title']
self.artist = from_dict['artist']
self.thumbnail = from_dict['thumbnail']
+ self.duration = from_dict['duration']
if not self.validate():
self.ready = "failed"
file_no_ext = match[1]
ext = match[2]
+ if ext in ("mp3", "ogg", "opus", "aac", "flac", "wav"):
+ self.duration = get_duration(self.uri())
+
try:
im = None
path_thumbnail = file_no_ext + ".jpg"
dict['title'] = self.title
dict['artist'] = self.artist
dict['thumbnail'] = self.thumbnail
+ dict['duration'] = self.duration
return dict
def format_debug_string(self):
def format_debug_string(self):
return self.id
+ def format_duration(self):
+ return '%d:%02d' % (self.duration // 60, self.duration % 60)
+
def display_type(self):
return ""
onclick="request('post', {action : 'stop'})" disabled>
<i class="fas fa-stop" aria-hidden="true"></i>
</button>
+ <span id="current-time" style="line-height: 200%">
+ </span>
</div>
<div class="btn-group" style="float: right;">
var playlist_ver = 0;
+ function format_duration(secs) {
+ return parseInt(secs/60) + ':' + ('0' + parseInt(secs%60)).slice(-2);
+ }
+
function request(url, _data, refresh=false){
$.ajax({
type: 'POST',
updatePlaylist();
playlist_ver = data.ver;
}
- updateControls(data.empty, data.play, data.mode);
+ updateControls(data);
}
}
});
});
}
- function updateControls(empty, play, mode){
+ function updateControls(data) {
+ var empty = data.empty;
+ var play = data.play;
+ var mode = data.mode;
if(empty){
$("#play-btn").prop("disabled", true);
$("#pause-btn").prop("disabled", true);
$("#random-btn").removeClass("btn-primary").addClass("btn-secondary").prop("disabled", false);
$("#autoplay-btn").removeClass("btn-secondary").addClass("btn-primary").prop("disabled", true);
}
-
+ var current_time = "";
+ if (data.playhead != -1) {
+ var duration = $('#playlist-table .table-active').data('duration');
+ if (duration) {
+ var elapsed = data.playhead;
+ current_time = format_duration(elapsed) + '/' + format_duration(duration);
+ }
+ }
+ $('#current-time').text(current_time);
}
function themeInit(){
updatePlaylist();
playlist_ver = data.ver;
}
- updateControls(data.empty, data.play, data.mode);
+ updateControls(data);
}
}
});
- } , 3000);
+ } , 1000);
themeInit();
$(document).ready(updatePlaylist);
</tr>
{% else %}
{% if index == playlist.current_index %}
-<tr class="table-active">
+<tr class="table-active" data-duration="{{ m.duration }}">
{% else %}
<tr>
{% endif %}
<span class="badge badge-secondary">{{ m.display_type() }}</span>
<br />
{% if m.type == 'file' %}
- {% if m.artist %}
- {{ m.artist }}
+ {% if m.duration %}
+ duration: {{ m.format_duration() }}
{% else %}
??
{% endif %}