0.10.2-14 DVD title Select
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ripster-backend",
|
"name": "ripster-backend",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ripster-backend",
|
"name": "ripster-backend",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver": "^7.0.1",
|
"archiver": "^7.0.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ripster-backend",
|
"name": "ripster-backend",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1449,6 +1449,28 @@ function pickScanTitleList(scanJson) {
|
|||||||
return alt || [];
|
return alt || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the HandBrake-selected main feature title ID (the "1 valid title" HandBrake reports).
|
||||||
|
// Present in the JSON as MainFeature at the top level or inside the Scan node.
|
||||||
|
function pickScanMainFeatureTitleId(scanJson) {
|
||||||
|
if (!scanJson || typeof scanJson !== 'object') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const direct = scanJson.MainFeature ?? scanJson.mainFeature ?? null;
|
||||||
|
if (direct != null) {
|
||||||
|
const id = Number(direct);
|
||||||
|
return Number.isFinite(id) && id > 0 ? id : null;
|
||||||
|
}
|
||||||
|
const scanNode = scanJson.Scan && typeof scanJson.Scan === 'object' ? scanJson.Scan : null;
|
||||||
|
if (scanNode) {
|
||||||
|
const nested = scanNode.MainFeature ?? scanNode.mainFeature ?? null;
|
||||||
|
if (nested != null) {
|
||||||
|
const id = Number(nested);
|
||||||
|
return Number.isFinite(id) && id > 0 ? id : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function resolvePlaylistInfoFromAnalysis(playlistAnalysis, playlistIdRaw) {
|
function resolvePlaylistInfoFromAnalysis(playlistAnalysis, playlistIdRaw) {
|
||||||
const playlistId = normalizePlaylistId(playlistIdRaw);
|
const playlistId = normalizePlaylistId(playlistIdRaw);
|
||||||
if (!playlistId || !playlistAnalysis) {
|
if (!playlistId || !playlistAnalysis) {
|
||||||
@@ -2094,6 +2116,14 @@ function parseHandBrakeSelectedTitleInfo(scanJson, options = {}) {
|
|||||||
.sort((a, b) => b.durationSeconds - a.durationSeconds || b.sizeBytes - a.sizeBytes || a.handBrakeTitleId - b.handBrakeTitleId);
|
.sort((a, b) => b.durationSeconds - a.durationSeconds || b.sizeBytes - a.sizeBytes || a.handBrakeTitleId - b.handBrakeTitleId);
|
||||||
selected = playlistMatches[0] || null;
|
selected = playlistMatches[0] || null;
|
||||||
}
|
}
|
||||||
|
// Use HandBrake's own MainFeature designation before falling back to heuristics.
|
||||||
|
// This is exactly the "1 valid title" HandBrake reports in text output.
|
||||||
|
if (!selected) {
|
||||||
|
const mainFeatureId = pickScanMainFeatureTitleId(scanJson);
|
||||||
|
if (mainFeatureId) {
|
||||||
|
selected = parsedTitles.find((title) => title.handBrakeTitleId === mainFeatureId) || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!selected) {
|
if (!selected) {
|
||||||
selected = parsedTitles
|
selected = parsedTitles
|
||||||
.slice()
|
.slice()
|
||||||
@@ -8193,6 +8223,7 @@ class PipelineService extends EventEmitter {
|
|||||||
|| rawMedia.source === 'single_extensionless';
|
|| rawMedia.source === 'single_extensionless';
|
||||||
let dvdHandBrakeScanJson = null;
|
let dvdHandBrakeScanJson = null;
|
||||||
let dvdHandBrakeScanInputPath = null;
|
let dvdHandBrakeScanInputPath = null;
|
||||||
|
let dvdSelectedTitleInfo = null; // set when HandBrake scan succeeds; used to skip re-selection
|
||||||
|
|
||||||
if (isDvdSource && mediaFiles.length > 0) {
|
if (isDvdSource && mediaFiles.length > 0) {
|
||||||
// For 'dvd': scan the folder that contains VIDEO_TS (parent of the VIDEO_TS dir).
|
// For 'dvd': scan the folder that contains VIDEO_TS (parent of the VIDEO_TS dir).
|
||||||
@@ -8234,6 +8265,7 @@ class PipelineService extends EventEmitter {
|
|||||||
if (dvdHandBrakeScanJson) {
|
if (dvdHandBrakeScanJson) {
|
||||||
const titleInfo = parseHandBrakeSelectedTitleInfo(dvdHandBrakeScanJson);
|
const titleInfo = parseHandBrakeSelectedTitleInfo(dvdHandBrakeScanJson);
|
||||||
if (titleInfo) {
|
if (titleInfo) {
|
||||||
|
dvdSelectedTitleInfo = titleInfo;
|
||||||
const syntheticMediaInfo = buildSyntheticMediaInfoFromMakeMkvTitle(titleInfo);
|
const syntheticMediaInfo = buildSyntheticMediaInfoFromMakeMkvTitle(titleInfo);
|
||||||
mediaInfoByPath[dvdHandBrakeScanInputPath] = syntheticMediaInfo;
|
mediaInfoByPath[dvdHandBrakeScanInputPath] = syntheticMediaInfo;
|
||||||
effectiveMediaFiles = [{ path: dvdHandBrakeScanInputPath, size: 0 }];
|
effectiveMediaFiles = [{ path: dvdHandBrakeScanInputPath, size: 0 }];
|
||||||
@@ -8415,11 +8447,23 @@ class PipelineService extends EventEmitter {
|
|||||||
'SYSTEM',
|
'SYSTEM',
|
||||||
`HandBrake Titel-Auswahl (manuell) übernommen: -t ${preSelectedHandBrakeTitleId}`
|
`HandBrake Titel-Auswahl (manuell) übernommen: -t ${preSelectedHandBrakeTitleId}`
|
||||||
);
|
);
|
||||||
|
} else if (dvdSelectedTitleInfo) {
|
||||||
|
// HandBrake already identified the valid title during the DVD analysis scan above.
|
||||||
|
// Use it directly — no need to re-parse all titles from TitleList, which would
|
||||||
|
// include short/invalid titles and incorrectly trigger manual title selection.
|
||||||
|
enrichedReview = {
|
||||||
|
...enrichedReview,
|
||||||
|
handBrakeTitleId: dvdSelectedTitleInfo.handBrakeTitleId,
|
||||||
|
encodeInputPath: dvdScanInputPath
|
||||||
|
};
|
||||||
|
await historyService.appendLog(
|
||||||
|
jobId,
|
||||||
|
'SYSTEM',
|
||||||
|
`HandBrake DVD Titel automatisch gewählt (aus Scan): -t ${dvdSelectedTitleInfo.handBrakeTitleId}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// Reuse the HandBrake scan result from the DVD analysis step when available,
|
// No pre-scanned result available — run a fresh HandBrake scan for title selection.
|
||||||
// otherwise run a fresh scan for title selection.
|
let dvdTitleScanJson = null;
|
||||||
let dvdTitleScanJson = dvdHandBrakeScanJson || null;
|
|
||||||
if (!dvdTitleScanJson) {
|
|
||||||
await historyService.appendLog(
|
await historyService.appendLog(
|
||||||
jobId,
|
jobId,
|
||||||
'SYSTEM',
|
'SYSTEM',
|
||||||
@@ -8447,7 +8491,6 @@ class PipelineService extends EventEmitter {
|
|||||||
collectStderrLines: false
|
collectStderrLines: false
|
||||||
});
|
});
|
||||||
dvdTitleScanJson = parseMediainfoJsonOutput(dvdTitleScanLines.join('\n'));
|
dvdTitleScanJson = parseMediainfoJsonOutput(dvdTitleScanLines.join('\n'));
|
||||||
}
|
|
||||||
if (dvdTitleScanJson) {
|
if (dvdTitleScanJson) {
|
||||||
const allTitles = parseHandBrakeTitleList(dvdTitleScanJson);
|
const allTitles = parseHandBrakeTitleList(dvdTitleScanJson);
|
||||||
const minLengthMinutes = Number(settings?.makemkv_min_length_minutes || 0);
|
const minLengthMinutes = Number(settings?.makemkv_min_length_minutes || 0);
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ripster-frontend",
|
"name": "ripster-frontend",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ripster-frontend",
|
"name": "ripster-frontend",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"primeicons": "^7.0.0",
|
"primeicons": "^7.0.0",
|
||||||
"primereact": "^10.9.2",
|
"primereact": "^10.9.2",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ripster-frontend",
|
"name": "ripster-frontend",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ripster",
|
"name": "ripster",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ripster",
|
"name": "ripster",
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"concurrently": "^9.1.2"
|
"concurrently": "^9.1.2"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ripster",
|
"name": "ripster",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.10.2-13",
|
"version": "0.10.2-14",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "concurrently \"npm run dev --prefix backend\" \"npm run dev --prefix frontend\"",
|
"dev": "concurrently \"npm run dev --prefix backend\" \"npm run dev --prefix frontend\"",
|
||||||
"dev:backend": "npm run dev --prefix backend",
|
"dev:backend": "npm run dev --prefix backend",
|
||||||
|
|||||||
Reference in New Issue
Block a user