Merge upstream master and update web dependencies

This commit is contained in:
Tyler Vigario 2020-06-09 17:16:31 -07:00
commit 66bf1f1510
No known key found for this signature in database
GPG Key ID: 4D670648A0376AA4
13 changed files with 105 additions and 62 deletions

View File

@ -31,6 +31,7 @@ username = botamusique
comment = Hi, I'm here to play radio, local music or youtube/soundcloud music. Have fun!
# default volume from 0 to 1.
volume = 0.1
stereo = True
# playback mode should be one of "one-shot", "repeat", "random", "autoplay"
playback_mode = one-shot
autoplay_length = 5

View File

@ -39,6 +39,9 @@ port = 64738
# 'admin': Users allowed to kill the bot, or ban URLs. Separated by ';'
#admin = User1;User2;
# 'stereo': After 1.4.0, mumble starts to support stereo stream. Enable this option for stereo
# stream transmission. Otherwise the bot will down mix stereo sound into mono.
#stereo = True
# 'volume' is default volume from 0 to 1.
# This option will be overridden by value in the database.

View File

@ -64,7 +64,7 @@ class ReverseProxied(object):
web = Flask(__name__)
web.config['TEMPLATES_AUTO_RELOAD'] = True
#web.config['TEMPLATES_AUTO_RELOAD'] = True
log = logging.getLogger("bot")
user = 'Remote Control'

View File

@ -38,12 +38,13 @@ class MumbleBot:
self.log.info(f"bot: botamusique version {self.version}, starting...")
signal.signal(signal.SIGINT, self.ctrl_caught)
self.cmd_handle = {}
self.volume_set = var.config.getfloat('bot', 'volume')
self.volume_set = var.config.getfloat('bot', 'volume', fallback=0.1)
if var.db.has_option('bot', 'volume'):
self.volume_set = var.db.getfloat('bot', 'volume')
self.volume = self.volume_set
self.stereo = var.config.getboolean('bot', 'stereo', fallback=True)
if args.channel:
self.channel = args.channel
else:
@ -62,6 +63,7 @@ class MumbleBot:
self.song_start_at = -1
self.last_ffmpeg_err = ""
self.read_pcm_size = 0
self.pcm_buffer_size = 0
# self.download_threads = []
self.wait_for_ready = False # flag for the loop are waiting for download to complete in the other thread
self.on_killing = threading.Lock() # lock to acquire when killing ffmpeg thread is asked but ffmpeg is not
@ -104,7 +106,9 @@ class MumbleBot:
self.username = var.config.get("bot", "username")
self.mumble = pymumble.Mumble(host, user=self.username, port=port, password=password, tokens=tokens,
debug=var.config.getboolean('debug', 'mumbleConnection'), certfile=certificate)
stereo=self.stereo,
debug=var.config.getboolean('debug', 'mumbleConnection'),
certfile=certificate)
self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, self.message_received)
self.mumble.set_codec_profile("audio")
@ -369,8 +373,11 @@ class MumbleBot:
else:
ffmpeg_debug = "warning"
channels = 2 if self.stereo else 1
self.pcm_buffer_size = 960*channels
command = ("ffmpeg", '-v', ffmpeg_debug, '-nostdin', '-i',
uri, '-ss', f"{start_from:f}", '-ac', '1', '-f', 's16le', '-ar', '48000', '-')
uri, '-ss', f"{start_from:f}", '-ac', str(channels), '-f', 's16le', '-ar', '48000', '-')
self.log.debug("bot: execute ffmpeg command: " + " ".join(command))
# The ffmpeg process is a thread
@ -381,7 +388,7 @@ class MumbleBot:
else:
pipe_rd, pipe_wd = None, None
self.thread = sp.Popen(command, stdout=sp.PIPE, stderr=pipe_wd, bufsize=480)
self.thread = sp.Popen(command, stdout=sp.PIPE, stderr=pipe_wd, bufsize=self.pcm_buffer_size)
def async_download_next(self):
# Function start if the next music isn't ready
@ -452,8 +459,8 @@ class MumbleBot:
self.song_start_at = time.time() - self.playhead
self.playhead = time.time() - self.song_start_at
raw_music = self.thread.stdout.read(480)
self.read_pcm_size += 480
raw_music = self.thread.stdout.read(self.pcm_buffer_size)
self.read_pcm_size += self.pcm_buffer_size
if self.redirect_ffmpeg_log:
try:
@ -476,7 +483,8 @@ class MumbleBot:
if not self.is_pause and (self.thread is None or self.thread.poll() is not None):
# bot is not paused, but ffmpeg thread has gone.
# indicate that last song has finished, or the bot just resumed from pause, or something is wrong.
if self.read_pcm_size < 481 and len(var.playlist) > 0 and var.playlist.current_index != -1 \
if self.read_pcm_size < self.pcm_buffer_size and len(var.playlist) > 0 \
and var.playlist.current_index != -1 \
and self.last_ffmpeg_err:
current = var.playlist.current_item()
self.log.error("bot: cannot play music %s", current.format_debug_string())
@ -770,7 +778,7 @@ if __name__ == '__main__':
var.tmp_folder = util.solve_filepath(var.config.get('bot', 'tmp_folder'))
var.cache = MusicCache(var.music_db)
if var.config.get("bot", "refresh_cache_on_startup", fallback=True):
if var.config.getboolean("bot", "refresh_cache_on_startup", fallback=True):
var.cache.build_dir_cache()
# ======================

View File

@ -1,5 +1,3 @@
opuslib==2.0.0
protobuf==3.4.0
flask
youtube-dl
python-magic
@ -7,5 +5,5 @@ Pillow
mutagen
requests
packaging
pymumble
pymumble>=1.2
pyradios

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

97
web/package-lock.json generated
View File

@ -1117,6 +1117,12 @@
"integrity": "sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==",
"dev": true
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
"@types/node": {
"version": "14.0.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.4.tgz",
@ -2877,9 +2883,9 @@
"dev": true
},
"eslint": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.1.0.tgz",
"integrity": "sha512-DfS3b8iHMK5z/YLSme8K5cge168I8j8o1uiVmFCgnnjxZQbCGyraF8bMl7Ju4yfBmCuxD7shOF7eqGkcuIHfsA==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.2.0.tgz",
"integrity": "sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@ -2888,10 +2894,10 @@
"cross-spawn": "^7.0.2",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^5.0.0",
"eslint-scope": "^5.1.0",
"eslint-utils": "^2.0.0",
"eslint-visitor-keys": "^1.1.0",
"espree": "^7.0.0",
"eslint-visitor-keys": "^1.2.0",
"espree": "^7.1.0",
"esquery": "^1.2.0",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
@ -2937,9 +2943,9 @@
}
},
"chalk": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
"integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@ -2971,15 +2977,21 @@
}
},
"eslint-scope": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
"integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"eslint-visitor-keys": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz",
"integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==",
"dev": true
},
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
@ -3091,23 +3103,24 @@
}
},
"eslint-plugin-import": {
"version": "2.20.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz",
"integrity": "sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg==",
"version": "2.21.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.21.1.tgz",
"integrity": "sha512-qYOOsgUv63vHof7BqbzuD+Ud34bXHxFJxntuAC1ZappFZXYbRIek3aJ7jc9i2dHDGDyZ/0zlO0cpioES265Lsw==",
"dev": true,
"requires": {
"array-includes": "^3.0.3",
"array.prototype.flat": "^1.2.1",
"array-includes": "^3.1.1",
"array.prototype.flat": "^1.2.3",
"contains-path": "^0.1.0",
"debug": "^2.6.9",
"doctrine": "1.5.0",
"eslint-import-resolver-node": "^0.3.2",
"eslint-module-utils": "^2.4.1",
"eslint-import-resolver-node": "^0.3.3",
"eslint-module-utils": "^2.6.0",
"has": "^1.0.3",
"minimatch": "^3.0.4",
"object.values": "^1.1.0",
"object.values": "^1.1.1",
"read-pkg-up": "^2.0.0",
"resolve": "^1.12.0"
"resolve": "^1.17.0",
"tsconfig-paths": "^3.9.0"
},
"dependencies": {
"doctrine": {
@ -3123,12 +3136,12 @@
}
},
"eslint-plugin-jsdoc": {
"version": "26.0.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-26.0.2.tgz",
"integrity": "sha512-KtZjqtM3Z8x84vQBFKGUyBbZRGXYHVWSJ2XyYSUTc8KhfFrvzQ/GXPp6f1M1/YCNzP3ImD5RuDNcr+OVvIZcBA==",
"version": "27.0.5",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-27.0.5.tgz",
"integrity": "sha512-LU2sclCdHe4ykYlb2Jb7Nk7L6xd8PfwANV1KRgwHV78kCo/D8aeTdinNZb8BpZQEmu4HbrY82SPZIvyYumHVTQ==",
"dev": true,
"requires": {
"comment-parser": "^0.7.4",
"comment-parser": "^0.7.5",
"debug": "^4.1.1",
"jsdoctypeparser": "^6.1.0",
"lodash": "^4.17.15",
@ -3214,14 +3227,14 @@
"dev": true
},
"espree": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.0.0.tgz",
"integrity": "sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz",
"integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==",
"dev": true,
"requires": {
"acorn": "^7.1.1",
"acorn": "^7.2.0",
"acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.1.0"
"eslint-visitor-keys": "^1.2.0"
},
"dependencies": {
"acorn": {
@ -3229,6 +3242,12 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz",
"integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==",
"dev": true
},
"eslint-visitor-keys": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz",
"integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==",
"dev": true
}
}
},
@ -6085,9 +6104,9 @@
"dev": true
},
"sass": {
"version": "1.26.7",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.26.7.tgz",
"integrity": "sha512-xgNazdkr6yvgHEfNaOjKtZzhDZmKYMCmoRKMPrTDo7YvjaITIzU2DDYsIUuN/atAg7/JOxPeCQHH7TtCo5Tq2g==",
"version": "1.26.8",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.26.8.tgz",
"integrity": "sha512-yvtzyrKLGiXQu7H12ekXqsfoGT/aTKeMDyVzCB675k1HYuaj0py63i8Uf4SI9CHXj6apDhpfwbUr3gGOjdpu2Q==",
"dev": true,
"requires": {
"chokidar": ">=2.0.0 <4.0.0"
@ -6839,6 +6858,18 @@
"repeat-string": "^1.6.1"
}
},
"tsconfig-paths": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
"integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==",
"dev": true,
"requires": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"strip-bom": "^3.0.0"
}
},
"tslib": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",

View File

@ -30,16 +30,16 @@
"babel-loader": "^8.1.0",
"core-js": "^3.6.5",
"css-loader": "^3.5.3",
"eslint": "^7.1.0",
"eslint": "^7.2.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jsdoc": "^26.0.2",
"eslint-plugin-import": "^2.21.1",
"eslint-plugin-jsdoc": "^27.0.5",
"eslint-plugin-node": "^11.1.0",
"html-webpack-plugin": "^4.3.0",
"mini-css-extract-plugin": "^0.9.0",
"postcss-loader": "^3.0.0",
"regenerator-runtime": "^0.13.5",
"sass": "^1.26.7",
"sass": "^1.26.8",
"sass-loader": "^8.0.2",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"

View File

@ -1057,6 +1057,7 @@ function playerSetIdle() {
playerTitle.textContent = '-- IDLE --';
playerArtist.textContent = '';
setProgressBar(playerBar, 0);
clearInterval(playhead_timer);
}
function updatePlayerInfo(item) {
@ -1118,9 +1119,9 @@ function updatePlayerPlayhead(playhead) {
setProgressBar(playerBar, player_playhead_position / currentPlayingItem.duration, secondsToStr(player_playhead_position));
if (playing) {
playhead_timer = setInterval(function() {
player_playhead_position += 0.1;
player_playhead_position += 0.3;
setProgressBar(playerBar, player_playhead_position / currentPlayingItem.duration, secondsToStr(player_playhead_position));
}, 100); // delay in milliseconds
}, 300); // delay in milliseconds
}
} else {
if (playing) {
@ -1142,7 +1143,7 @@ playerBarBox.addEventListener('mousedown', function() {
playerBarBox.addEventListener('mouseup', function(event) {
playerBarBox.removeEventListener('mousemove', playheadDragged);
const percent = event.offsetX / playerBarBox.clientWidth;
const percent = (event.clientX - playerBarBox.getBoundingClientRect().x) / playerBarBox.clientWidth;
request('post', {
move_playhead: percent * currentPlayingItem.duration,
});
@ -1150,7 +1151,7 @@ playerBarBox.addEventListener('mouseup', function(event) {
});
function playheadDragged(event) {
const percent = event.offsetX / playerBarBox.clientWidth;
const percent = (event.clientX - playerBarBox.getBoundingClientRect().x) / playerBarBox.clientWidth;
setProgressBar(playerBar, percent, secondsToStr(percent * currentPlayingItem.duration));
}

View File

@ -2,10 +2,11 @@ export function isOverflown(element) {
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
export function setProgressBar(bar, progress, text='') {
const progStr = (progress*100).toString();
export function setProgressBar(bar, progress, text = '') {
const progPos = (-1 * (1 - progress) * bar.scrollWidth).toString();
const progStr = (progress * 100).toString();
bar.setAttribute('aria-valuenow', progStr);
bar.style.width = progStr + '%';
bar.style.transform = "translateX(" + progPos + "px)";
bar.textContent = text;
}

View File

@ -425,7 +425,7 @@
</div>
<span id="playerArtist">Artist</span>
<div id="playerBarBox" class="progress">
<div id="playerBar" class="progress-bar" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>
<div id="playerBar" class="progress-bar pr-2" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 100%; text-align: right; transform: translateX(-100%);"></div>
</div>
</div>
</div>
@ -493,7 +493,7 @@
<span class="uploadItemTitle mr-3"></span>
<span class="uploadItemError text-danger"></span>
<div class="progress" style="margin-top: 5px; height: 10px;">
<div class="uploadProgress progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<div class="uploadProgress progress-bar pr-2" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 100%; text-align: right; transform: translateX(-100%);"></div>
</div>
</div>
</div>