various fixups, allow FTP max size config
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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"]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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++]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user