Fix: direct .gves→hires lookup, add /hires-media mount, debug logging
- Added /mnt/Hitchcock/bmg_video/Media as read-only bind mount at /hires-media in container - Added direct .gves→hires fallback that works even when proxyLinks is empty - For each .gves block, searches unlinked high-res proxy block titles against media folder - Added console logging to trace the lookup process for debugging - This handles the case where FramelightX creates no explicit linkages at all
This commit is contained in:
parent
c29245758c
commit
36e104ebdd
2 changed files with 76 additions and 34 deletions
|
|
@ -38,6 +38,8 @@ services:
|
|||
- /mnt/smb-ame/Watch:/watch
|
||||
- /mnt/smb-ame/Output:/output
|
||||
- /mnt/smb-ame/Logs:/ame-logs
|
||||
# High-res media folder for fallback lookup
|
||||
- /mnt/Hitchcock/bmg_video/Media:/hires-media:ro
|
||||
|
||||
volumes:
|
||||
app_data:
|
||||
|
|
|
|||
|
|
@ -246,6 +246,8 @@ function parseProxyLinks(xml, mediaBlocks) {
|
|||
function findHighResFileForGves(gvesPath, hiresTitle, hiresMediaFolder, fs) {
|
||||
if (!hiresMediaFolder) return null;
|
||||
|
||||
console.log(`[HIRES LOOKUP] Searching for title="${hiresTitle}" in folder="${hiresMediaFolder}"`);
|
||||
|
||||
try {
|
||||
// Normalize the folder path
|
||||
const searchFolder = hiresMediaFolder.replace(/\\/g, '/').replace(/\/$/, '');
|
||||
|
|
@ -266,6 +268,7 @@ function findHighResFileForGves(gvesPath, hiresTitle, hiresMediaFolder, fs) {
|
|||
// Match if filename contains the title
|
||||
if (fileLower.includes(titleLower)) {
|
||||
const fullPath = `${searchFolder}/${file}`;
|
||||
console.log(`[HIRES LOOKUP] MATCH FOUND: "${file}" contains "${hiresTitle}"`);
|
||||
return fullPath.replace(/\//g, '\\');
|
||||
}
|
||||
}
|
||||
|
|
@ -406,56 +409,93 @@ function performSwaps(xml, mediaBlocks, proxyLinks, options = {}) {
|
|||
);
|
||||
}
|
||||
|
||||
// Handle unlinked high-res proxy blocks (have IsProxy: true, FilePath: null, no proxyLinks entry)
|
||||
// These occur when FramelightX created proxy blocks but didn't link them explicitly
|
||||
if (options.hiresMediaFolder && allGvesBlocks.length > 0) {
|
||||
// Get the first .gves block as reference (for path lookup)
|
||||
const gvesRef = allGvesBlocks[0].block;
|
||||
// ─── Direct .gves → high-res lookup (when proxyLinks is empty) ───
|
||||
// When FramelightX doesn't create explicit proxy linkages, we need to
|
||||
// directly find high-res files for each .gves block in the media folder.
|
||||
if (options.hiresMediaFolder) {
|
||||
const processedGves = new Set(gvesUids); // Already handled above
|
||||
|
||||
for (const [uid, hiresBlock] of Object.entries(mediaBlocks)) {
|
||||
// Skip if already processed, not a proxy, or already has a path
|
||||
if (gvesUids.includes(uid) || !hiresBlock.isProxy || hiresBlock.filePath) continue;
|
||||
for (const { uid: gvesUid, block: gvesBlock } of allGvesBlocks) {
|
||||
if (processedGves.has(gvesUid)) continue;
|
||||
|
||||
// Try to find a high-res file for this unlinked proxy using its Title
|
||||
// Extract the .gves filename to use as a lookup key
|
||||
const gvesFilename = gvesBlock.filePath.split('\\').pop().split('/').pop();
|
||||
const gvesBaseName = gvesFilename.replace(/\.[^.]+$/, '');
|
||||
|
||||
// Try to find a matching high-res file using the .gves block's title
|
||||
// or by searching the high-res media folder
|
||||
let hiresPath = findHighResFileForGves(
|
||||
gvesRef.filePath, // Use first gves path for reference
|
||||
hiresBlock.title,
|
||||
gvesBlock.filePath,
|
||||
gvesBlock.title,
|
||||
options.hiresMediaFolder,
|
||||
fs
|
||||
);
|
||||
|
||||
// Also try matching against unlinked high-res proxy blocks' titles
|
||||
if (!hiresPath) {
|
||||
for (const [huid, hblock] of Object.entries(mediaBlocks)) {
|
||||
if (!hblock.isProxy || hblock.filePath) continue;
|
||||
hiresPath = findHighResFileForGves(
|
||||
gvesBlock.filePath,
|
||||
hblock.title,
|
||||
options.hiresMediaFolder,
|
||||
fs
|
||||
);
|
||||
if (hiresPath) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hiresPath) continue;
|
||||
|
||||
const hiresTitle = hiresBlock.title || pathToTitle(hiresPath);
|
||||
const hiresTitle = pathToTitle(hiresPath);
|
||||
const gvesPath = gvesBlock.filePath;
|
||||
const gvesPathEscaped = escapeRegex(gvesPath);
|
||||
|
||||
// Perform replacements for this unlinked proxy
|
||||
// We'll replace the Title in the XML with the found file
|
||||
if (hiresBlock.title) {
|
||||
const titleEscaped = escapeRegex(hiresBlock.title);
|
||||
console.log(`[FALLBACK SWAP] ${gvesPath} → ${hiresPath}`);
|
||||
|
||||
swaps.push({
|
||||
gvesUid,
|
||||
hiresUid: 'direct-lookup',
|
||||
oldPath: gvesPath,
|
||||
newPath: hiresPath,
|
||||
newTitle: hiresTitle
|
||||
});
|
||||
|
||||
// Replace FilePath tags
|
||||
remappedXml = remappedXml.replace(
|
||||
new RegExp(`<Title>${titleEscaped}</Title>`, 'g'),
|
||||
new RegExp(`<FilePath>${gvesPathEscaped}</FilePath>`, 'g'),
|
||||
`<FilePath>${hiresPath}</FilePath>`
|
||||
);
|
||||
|
||||
// Replace ActualMediaFilePath tags
|
||||
remappedXml = remappedXml.replace(
|
||||
new RegExp(`<ActualMediaFilePath>${gvesPathEscaped}</ActualMediaFilePath>`, 'g'),
|
||||
`<ActualMediaFilePath>${hiresPath}</ActualMediaFilePath>`
|
||||
);
|
||||
|
||||
// Replace RelativePath tags
|
||||
if (gvesBlock.relativePath) {
|
||||
const relPathEscaped = escapeRegex(gvesBlock.relativePath);
|
||||
remappedXml = remappedXml.replace(
|
||||
new RegExp(`<RelativePath>${relPathEscaped}</RelativePath>`, 'g'),
|
||||
`<RelativePath>${hiresPath}</RelativePath>`
|
||||
);
|
||||
}
|
||||
|
||||
// Replace Title tags that match the .gves filename
|
||||
if (gvesFilename) {
|
||||
const gvesTitleEscaped = escapeRegex(gvesFilename);
|
||||
remappedXml = remappedXml.replace(
|
||||
new RegExp(`<Title>${gvesTitleEscaped}</Title>`, 'g'),
|
||||
`<Title>${hiresTitle}</Title>`
|
||||
);
|
||||
}
|
||||
|
||||
// Add a FilePath to the high-res block's Media section
|
||||
// Look for the Media block with this Title and add FilePath if missing
|
||||
const mediaBlockRegex = new RegExp(
|
||||
`<Media[^>]*>([^<]*<Title>${escapeRegex(hiresBlock.title)}</Title>[^<]*)</Media>`,
|
||||
'g'
|
||||
// Replace ImplementationID
|
||||
remappedXml = remappedXml.replace(
|
||||
new RegExp(`<ImplementationID>${escapeRegex(FRAMELIGHTX_IMPL_ID)}</ImplementationID>`, 'g'),
|
||||
`<ImplementationID>${NULL_IMPL_ID}</ImplementationID>`
|
||||
);
|
||||
remappedXml = remappedXml.replace(mediaBlockRegex, (match) => {
|
||||
if (match.includes('<FilePath>')) return match; // Already has path
|
||||
return match.replace(`</Media>`, `<FilePath>${hiresPath}</FilePath></Media>`);
|
||||
});
|
||||
|
||||
swaps.push({
|
||||
gvesUid: 'unlinked',
|
||||
hiresUid: uid,
|
||||
oldPath: 'null',
|
||||
newPath: hiresPath,
|
||||
newTitle: hiresTitle
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue