Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve web-upload progress status + minor fixes #139

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 69 additions & 16 deletions html/management_DE.html
Expand Up @@ -4,7 +4,7 @@
<title>ESPuino-Konfiguration</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/x-icon" href="https://espuino.de/espuino/favicon.ico">
<link rel="shortcut icon" type="image/x-icon" href="/favicon">
<link rel="stylesheet" href="https://espuino.de/espuino/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"/>
Expand Down Expand Up @@ -137,7 +137,7 @@
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<div class="col-md-12">
<a class="float-left navbar-brand">
<img src="https://www.espuino.de/espuino/Espuino32.png"
<img src="/logo"
width="35" height="35" class="d-inline-block align-top" alt=""/>
ESPuino
</a>
Expand Down Expand Up @@ -191,7 +191,7 @@
<div class="form-group col-md-12">
<legend>Steuerung</legend>
<div class="form-group col-md-12">
<img src="/cover" class="coverimage-container" id="coverimg">
<img src="/cover" class="coverimage-container" id="coverimg" alt="">
</div>
<div class="buttons">
<button type="button" class="btn btn-default btn-lg" id="nav-btn-first" onclick="sendControl(173)">
Expand All @@ -201,7 +201,7 @@
<span class="fas fa-backward"></span>
</button>
<button type="button" class="btn btn-default btn-lg" id="nav-btn-play" onclick="sendControl(170)">
<i id="ico-play-pause" class='fas fa-lg fa-play')></i>
<i id="ico-play-pause" class="fas fa-lg fa-play"></i>
</button>
<button type="button" class="btn btn-default btn-lg" id="nav-btn-next" onclick="sendControl(172)">
<span class="fas fa-forward"></span>
Expand Down Expand Up @@ -576,7 +576,6 @@
"newestOnTop": false,
"progressBar": false,
"positionClass": "toast-top-right",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
Expand All @@ -599,15 +598,20 @@
}).pop();
if ((/\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|flac|FLAC|m4a|M4A)$/i).test(lastFolder)) {
data.instance.set_type(data.instance._model.data[key], 'audio');
} else
if ((/\.(png|PNG|jpg|JPG|jpeg|JPEG|bmp|BMP|gif|GIF)$/i).test(lastFolder)) {
data.instance.set_type(data.instance._model.data[key], 'image');
data.instance.disable_node(data.instance._model.data[key]);
} else {
if (data.instance._model.data[key]['type'] == "file") {
if (data.instance._model.data[key]['type'] == "file") {
data.instance.disable_node(data.instance._model.data[key]);
}
}
data.instance.rename_node(data.instance._model.data[key], lastFolder);
});
}


/* File Explorer functions begin*/
var lastSelectedNodePath = "";

Expand Down Expand Up @@ -733,23 +737,64 @@
contentType: false,
processData:false,
xhr: function() {
var lastNow = new Date().getTime();
startTime = new Date().getTime();
var lastKBytes = 0;
bytesTotal = 0;
var xhr = new window.XMLHttpRequest();

xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var now = new Date().getTime();
bytesTotal = evt.total;
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
console.log(percentComplete);
kbytes = evt.loaded / 1024;
var uploadedkBytes = kbytes - lastKBytes;
var elapsed = (now - lastNow) / 1000;
elapsed_total = (now - startTime) / 1000;
var kbps = elapsed ? uploadedkBytes / elapsed : 0;
lastKBytes = kbytes;
lastNow = now;

var seconds_elapsed = (now - startTime) / 1000;
var bytes_per_second = seconds_elapsed ? evt.loaded / seconds_elapsed : 0;
var Kbytes_per_second = bytes_per_second / 1024;
var remaining_bytes = evt.total - evt.loaded;
var seconds_remaining = seconds_elapsed ? (remaining_bytes / bytes_per_second) : 'wird berechnet..' ;

var percent = percentComplete + '%';
$("#explorerUploadProgress").css('width', percent).text(percent);
console.log("Percent: " + percent + ", " + Kbytes_per_second.toFixed(2) + " KB/s");
var progressText = percent;
if (seconds_remaining > 60) {
progressText = progressText + ", " + (seconds_remaining / 60).toFixed(0) + " Min. verbleibend..";
} else
if (seconds_remaining <= 0) {
progressText = progressText + " (" + Kbytes_per_second.toFixed(2) + " KB/s)";
} else
if (seconds_remaining < 2) {
progressText = progressText + ", wenige Sek. verbleibend..";
} else {
progressText = progressText + ", " + seconds_remaining.toFixed(0) + " Sek. verbleibend..";
}
$("#explorerUploadProgress").css('width', percent).text(progressText);
}
}, false);

return xhr;
},
success: function(data, textStatus, jqXHR) {
console.log("Upload success!");
$("#explorerUploadProgress").text("Upload success!");
var now = new Date().getTime();
var elapsed_time = (now - startTime);
var seconds_elapsed = elapsed_time / 1000;
var bytes_per_second = seconds_elapsed ? bytesTotal / seconds_elapsed : 0;
var Kbytes_per_second = bytes_per_second / 1024 ;
var minutes = Math.floor(seconds_elapsed / 60);
var seconds = seconds_elapsed - (minutes * 60);
var timeText = minutes.toString().padStart(2, '0') + ':' + seconds.toFixed(0).toString().padStart(2, '0');
console.log("Upload success (" + timeText + ", " + Kbytes_per_second.toFixed(2) + " KB/s): " + textStatus);
var progressText = "Upload abgeschlossen (" + timeText + ", " + Kbytes_per_second.toFixed(2) + " KB/s).";
$("#explorerUploadProgress").text(progressText);
document.getElementById('uploaded_file').value = '';
document.getElementById('uploaded_file_text').innerHTML = '';

Expand All @@ -758,11 +803,14 @@
deleteChildrenNodes(sel);
addFileDirectory(sel, data);
ref.open_node(sel);


});

}
},
error: function(request, status, error) {
console.log("Upload ERROR!");
$("#explorerUploadProgress").text("Upload-Fehler: " + status);
toastr.error("Upload-Fehler: " + status);
}
});
});

Expand Down Expand Up @@ -846,6 +894,8 @@
type = "folder";
} else if ((/\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|m4a|M4A|flac|FLAC)$/i).test(data.name)) {
type = "audio";
} else if ((/\.(png|PNG|jpg|JPG|jpeg|JPEG|bmp|BMP|gif|GIF)$/i).test(data.name)) {
type = "image";
} else {
type = "file";
}
Expand Down Expand Up @@ -893,6 +943,9 @@
'audio': {
'icon': "fa fa-file-audio"
},
'image': {
'icon': "fa fa-file-image"
},
'default': {
'icon': "fa fa-folder"
}
Expand Down Expand Up @@ -1040,7 +1093,7 @@
toastr.success("Aktion erfolgreich ausgeführt." );
}
} if ("pong" in socketMsg) {
if (socketMsg.pong == 'pong') {
if (socketMsg.pong == 'pong') {
pong();
}
} if ("volume" in socketMsg) {
Expand All @@ -1050,9 +1103,9 @@

var btnTrackPlayPause = document.getElementById('nav-btn-play');
if (socketMsg.trackinfo.pausePlay) {
btnTrackPlayPause.innerHTML = '<i id="ico-play-pause" class="fas fa-lg fa-play")></i>';
btnTrackPlayPause.innerHTML = '<i id="ico-play-pause" class="fas fa-lg fa-play"></i>';
} else {
btnTrackPlayPause.innerHTML = '<i id="ico-play-pause" class="fas fa-lg fa-pause")></i>';
btnTrackPlayPause.innerHTML = '<i id="ico-play-pause" class="fas fa-lg fa-pause"></i>';
}

var btnTrackFirst = document.getElementById('nav-btn-first');
Expand Down
24 changes: 12 additions & 12 deletions src/AudioPlayer.cpp
Expand Up @@ -100,8 +100,9 @@ void AudioPlayer_Init(void) {
// Adjust volume depending on headphone is connected and volume-adjustment is enabled
AudioPlayer_SetupVolume();

// delete cover image
gPlayProperties.coverFileName = NULL;
// clear cover image
gPlayProperties.coverFilePos = 0;

if (System_GetOperationMode() == OPMODE_NORMAL) { // Don't start audio-task in BT-mode!
xTaskCreatePinnedToCore(
AudioPlayer_Task, /* Function to implement the task */
Expand Down Expand Up @@ -365,8 +366,8 @@ void AudioPlayer_Task(void *parameter) {
gPlayProperties.title = NULL;
}
Web_SendWebsocketData(0, 30);
// delete cover image
gPlayProperties.coverFileName = NULL;
// clear cover image
gPlayProperties.coverFilePos = 0;
Web_SendWebsocketData(0, 40);
continue;

Expand Down Expand Up @@ -459,8 +460,8 @@ void AudioPlayer_Task(void *parameter) {
free(gPlayProperties.title);
gPlayProperties.title = NULL;
}
// delete cover image
gPlayProperties.coverFileName = NULL;
// clear cover image
gPlayProperties.coverFilePos = 0;
Web_SendWebsocketData(0, 40);
audioReturnCode = audio->connecttoFS(gFSystem, *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber));
// consider track as finished, when audio lib call was not successful
Expand Down Expand Up @@ -599,8 +600,8 @@ void AudioPlayer_Task(void *parameter) {
free(gPlayProperties.title);
gPlayProperties.title = NULL;
}
// delete cover image
gPlayProperties.coverFileName = NULL;
// clear cover image
gPlayProperties.coverFilePos = 0;
Web_SendWebsocketData(0, 40);
audioReturnCode = audio->connecttohost(*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber));
gPlayProperties.playlistFinished = false;
Expand All @@ -618,8 +619,8 @@ void AudioPlayer_Task(void *parameter) {
free(gPlayProperties.title);
gPlayProperties.title = NULL;
}
// delete cover image
gPlayProperties.coverFileName = NULL;
// clear cover image
gPlayProperties.coverFilePos = 0;
Web_SendWebsocketData(0, 40);
audioReturnCode = audio->connecttoFS(gFSystem, *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber));
// consider track as finished, when audio lib call was not successful
Expand Down Expand Up @@ -1189,8 +1190,7 @@ void audio_lasthost(const char *info) { //stream URL played

// id3 tag: save cover image
void audio_id3image(File& file, const size_t pos, const size_t size) {
// save cover image file and position/size for later use
gPlayProperties.coverFileName = (char *)(file.name());
// save cover image position and size for later use
gPlayProperties.coverFilePos = pos;
gPlayProperties.coverFileSize = size;
// websocket notify cover image has changed
Expand Down
1 change: 0 additions & 1 deletion src/AudioPlayer.h
Expand Up @@ -25,7 +25,6 @@ typedef struct { // Bit field
bool tellIpAddress: 1; // If true current IP-address is spoken
bool currentSpeechActive: 1; // If speech-play is active
bool lastSpeechActive: 1; // If speech-play was active
char *coverFileName; // current coverfile
size_t coverFilePos; // current cover file position
size_t coverFileSize; // current cover file size
} playProps;
Expand Down