various fixups, allow FTP max size config

This commit is contained in:
zefie
2026-05-04 08:38:22 -04:00
parent cf9cc22a1c
commit 00e385cdbe
5 changed files with 18 additions and 25 deletions

View File

@@ -197,10 +197,12 @@ if (minisrv_config.services["wtv-author"].max_pages) {
</table> </table>
<p>A maximum of <b>${minisrv_config.services["wtv-author"].max_pages}</b> pages can be created, regardless of publish status. <p>A maximum of <b>${minisrv_config.services["wtv-author"].max_pages}</b> pages can be created, regardless of publish status.
<br><br> <br><br>
Your published pages are available at<br> `
if (numofpages > 0) {
`Your published pages are available at<br>
<a href="http://${site}/${session_data.getSessionData("subscriber_username")}/">http://${site}/${session_data.getSessionData("subscriber_username")}/</a> <a href="http://${site}/${session_data.getSessionData("subscriber_username")}/">http://${site}/${session_data.getSessionData("subscriber_username")}/</a>
</table>` </table>`
}
} }
data += ` data += `
<SCRIPT language=JavaScript> <SCRIPT language=JavaScript>

View File

@@ -72,6 +72,8 @@ async function processLC2DownloadPage(flashrom_info, headers, numparts = null) {
downloadTime = elapsedMinutes * remainingParts; downloadTime = elapsedMinutes * remainingParts;
} }
session.lastDownloadTime = now; session.lastDownloadTime = now;
if (isNaN(downloadTime) || downloadTime < 1) downloadTime = 1;
headers = `200 OK headers = `200 OK
@@ -127,7 +129,7 @@ Updating now
<font size=+1> <font size=+1>
Your ${session_data.getBoxName()} is being<br>updated automatically. Your ${session_data.getBoxName()} is being<br>updated automatically.
<p> <font size=+1> <p> <font size=+1>
This will take about ${downloadTime} minutes and<br>then you can use your ${session_data.getBoxName()} again. This will take about ${downloadTime} minute${downloadTime !== 1 ? "s" : ""} and<br>then you can use your ${session_data.getBoxName()} again.
`; `;
if (flashrom_info.is_bootrom && flashrom_info.part_number === (flashrom_info.part_count - 1)) { if (flashrom_info.is_bootrom && flashrom_info.part_number === (flashrom_info.part_count - 1)) {
data += `<p> data += `<p>

View File

@@ -70,7 +70,7 @@ class WTVFTP {
stream.on('data', (chunk) => { stream.on('data', (chunk) => {
chunks.push(chunk); chunks.push(chunk);
totalsize += chunk.length; totalsize += chunk.length;
if (totalsize > 1024 * 1024 * 4) { if (totalsize > 1024 * 1024 * this.minisrv_config.services[this.service_name].max_response_size) {
this.sendToClient(socket, { 'Status': '413 The item chosen contains too much information to be used.', 'Content-Type': 'text/plain' }, 'Item too large'); this.sendToClient(socket, { 'Status': '413 The item chosen contains too much information to be used.', 'Content-Type': 'text/plain' }, 'Item too large');
ftpClient.end(); ftpClient.end();
return; return;

View File

@@ -351,6 +351,7 @@
"ftp": { "ftp": {
"port": 1650, "port": 1650,
"connections": 3, "connections": 3,
"max_response_size": 8, // Megabytes
"handler_module": "WTVFTP", "handler_module": "WTVFTP",
"handler_extra_vars": ["wtvmime"] "handler_extra_vars": ["wtvmime"]
}, },

View File

@@ -225,45 +225,33 @@ function buildWebTVPS(videoES, audioES, outputPath, audioIntervalOverride, baHea
return false; return false;
} }
// Match known-working WebTV cadence (attract.mpg is ~1 audio per 7 video packs) // Use natural A/V ratio — matches actual bitrate split in the encoded file.
const inferredInterval = Math.max(1, Math.round(vChunks.length / aChunks.length)); // attract.mpg uses 7 because its video bitrate is ~7x its audio bitrate.
// Our encoded video is lower bitrate so the natural ratio is ~3.
const naturalInterval = Math.max(1, Math.round(vChunks.length / aChunks.length));
const audioInterval = Number.isFinite(audioIntervalOverride) && audioIntervalOverride > 0 const audioInterval = Number.isFinite(audioIntervalOverride) && audioIntervalOverride > 0
? Math.floor(audioIntervalOverride) ? Math.floor(audioIntervalOverride)
: Math.max(1, Math.round((inferredInterval + 7) / 2)); : naturalInterval;
console.log(`[*] ${vChunks.length} video chunks, ${aChunks.length} audio chunks, ` + console.log(`[*] ${vChunks.length} video chunks, ${aChunks.length} audio chunks, ` +
`1 audio per ~${audioInterval} video`); `1 audio per ~${audioInterval} video`);
const packs = []; const packs = [];
let aIdx = 0; let aIdx = 0;
// Pre-fill: 3 audio packs to prime the WebTV audio buffer // Pre-fill: 3 audio packs to prime the WebTV audio buffer (matches attract.mpg)
const preFill = Math.min(3, aChunks.length); const preFill = Math.min(3, aChunks.length);
for (let k = 0; k < preFill; k++, aIdx++) { for (let k = 0; k < preFill; k++, aIdx++) {
packs.push(makePack(0xC0, aChunks[aIdx])); packs.push(makePack(0xC0, aChunks[aIdx]));
} }
// Simple fixed-interval interleave: emit audioInterval video packs, then 1 audio pack
let vIdx = 0; let vIdx = 0;
// Spread audio over the full video timeline to avoid starving early playback
// and dumping remaining audio at EOF.
while (vIdx < vChunks.length || aIdx < aChunks.length) { while (vIdx < vChunks.length || aIdx < aChunks.length) {
if (vIdx >= vChunks.length) { for (let k = 0; k < audioInterval && vIdx < vChunks.length; k++) {
packs.push(makePack(0xC0, aChunks[aIdx++]));
continue;
}
if (aIdx >= aChunks.length) {
packs.push(makePack(0xE0, vChunks[vIdx++])); packs.push(makePack(0xE0, vChunks[vIdx++]));
continue;
} }
if (aIdx < aChunks.length) {
const videoProgress = vIdx / vChunks.length;
const audioProgress = aIdx / aChunks.length;
// Prefer video until audio falls behind target cadence.
if (audioProgress + (1 / Math.max(1, audioInterval * aChunks.length)) < videoProgress) {
packs.push(makePack(0xC0, aChunks[aIdx++])); packs.push(makePack(0xC0, aChunks[aIdx++]));
} else {
packs.push(makePack(0xE0, vChunks[vIdx++]));
} }
} }