refactor: Update merge output format handling
This commit is contained in:
@@ -5,21 +5,21 @@ import { IMAGES_DIR, SUBTITLES_DIR, VIDEOS_DIR } from "../../config/paths";
|
|||||||
import { DownloadCancelledError } from "../../errors/DownloadErrors";
|
import { DownloadCancelledError } from "../../errors/DownloadErrors";
|
||||||
import { bccToVtt } from "../../utils/bccToVtt";
|
import { bccToVtt } from "../../utils/bccToVtt";
|
||||||
import {
|
import {
|
||||||
calculateDownloadedSize,
|
calculateDownloadedSize,
|
||||||
formatBytes,
|
formatBytes,
|
||||||
isCancellationError,
|
isCancellationError,
|
||||||
isDownloadActive,
|
isDownloadActive,
|
||||||
parseSize,
|
parseSize,
|
||||||
} from "../../utils/downloadUtils";
|
} from "../../utils/downloadUtils";
|
||||||
import {
|
import {
|
||||||
extractBilibiliVideoId,
|
extractBilibiliVideoId,
|
||||||
formatVideoFilename,
|
formatVideoFilename,
|
||||||
} from "../../utils/helpers";
|
} from "../../utils/helpers";
|
||||||
import {
|
import {
|
||||||
executeYtDlpJson,
|
executeYtDlpJson,
|
||||||
executeYtDlpSpawn,
|
executeYtDlpSpawn,
|
||||||
getNetworkConfigFromUserConfig,
|
getNetworkConfigFromUserConfig,
|
||||||
getUserYtDlpConfig,
|
getUserYtDlpConfig,
|
||||||
} from "../../utils/ytDlpUtils";
|
} from "../../utils/ytDlpUtils";
|
||||||
import * as storageService from "../storageService";
|
import * as storageService from "../storageService";
|
||||||
import { Collection, Video } from "../storageService";
|
import { Collection, Video } from "../storageService";
|
||||||
@@ -214,7 +214,7 @@ export class BilibiliDownloader {
|
|||||||
}> {
|
}> {
|
||||||
try {
|
try {
|
||||||
const videoUrl = `https://www.bilibili.com/video/${videoId}`;
|
const videoUrl = `https://www.bilibili.com/video/${videoId}`;
|
||||||
|
|
||||||
// Get user config for network options
|
// Get user config for network options
|
||||||
const userConfig = getUserYtDlpConfig(videoUrl);
|
const userConfig = getUserYtDlpConfig(videoUrl);
|
||||||
const networkConfig = getNetworkConfigFromUserConfig(userConfig);
|
const networkConfig = getNetworkConfigFromUserConfig(userConfig);
|
||||||
@@ -331,30 +331,39 @@ export class BilibiliDownloader {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare base flags from user config (excluding certain overridden options)
|
// Prepare base flags from user config (excluding output options we manage)
|
||||||
const {
|
const {
|
||||||
output: _output,
|
output: _output,
|
||||||
o: _o,
|
o: _o,
|
||||||
writeSubs: _writeSubs,
|
|
||||||
writeAutoSubs: _writeAutoSubs,
|
|
||||||
convertSubs: _convertSubs,
|
|
||||||
f: _f,
|
f: _f,
|
||||||
format: _format,
|
format: _format,
|
||||||
S: _S,
|
S: _S,
|
||||||
formatSort: _formatSort,
|
formatSort: _formatSort,
|
||||||
|
// Extract user subtitle preferences (use them if provided)
|
||||||
|
writeSubs: userWriteSubs,
|
||||||
|
writeAutoSubs: userWriteAutoSubs,
|
||||||
|
convertSubs: userConvertSubs,
|
||||||
|
// Extract user merge output format (use it if provided)
|
||||||
|
mergeOutputFormat: userMergeOutputFormat,
|
||||||
...safeUserConfig
|
...safeUserConfig
|
||||||
} = userConfig;
|
} = userConfig;
|
||||||
|
|
||||||
|
// Determine merge output format: use user's choice or default to mp4
|
||||||
|
const mergeOutputFormat = userMergeOutputFormat || "mp4";
|
||||||
|
console.log(`Using merge output format: ${mergeOutputFormat}`);
|
||||||
|
|
||||||
// Prepare flags for yt-dlp - merge user config with required settings
|
// Prepare flags for yt-dlp - merge user config with required settings
|
||||||
const flags: Record<string, any> = {
|
const flags: Record<string, any> = {
|
||||||
...networkConfig, // Apply network settings
|
...networkConfig, // Apply network settings
|
||||||
...safeUserConfig, // Apply other user config
|
...safeUserConfig, // Apply other user config
|
||||||
output: outputTemplate,
|
output: outputTemplate,
|
||||||
format: downloadFormat,
|
format: downloadFormat,
|
||||||
mergeOutputFormat: "mp4",
|
// Use user preferences if provided, otherwise use defaults
|
||||||
writeSubs: true,
|
mergeOutputFormat: mergeOutputFormat,
|
||||||
writeAutoSubs: true,
|
writeSubs: userWriteSubs !== undefined ? userWriteSubs : true,
|
||||||
convertSubs: "vtt",
|
writeAutoSubs:
|
||||||
|
userWriteAutoSubs !== undefined ? userWriteAutoSubs : true,
|
||||||
|
convertSubs: userConvertSubs !== undefined ? userConvertSubs : "vtt",
|
||||||
ignoreErrors: true, // Continue even if subtitle download fails
|
ignoreErrors: true, // Continue even if subtitle download fails
|
||||||
noWarnings: false, // Show warnings for debugging
|
noWarnings: false, // Show warnings for debugging
|
||||||
};
|
};
|
||||||
@@ -857,12 +866,16 @@ export class BilibiliDownloader {
|
|||||||
`Downloading Bilibili part ${partNumber}/${totalParts}: ${url}`
|
`Downloading Bilibili part ${partNumber}/${totalParts}: ${url}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Get user's yt-dlp configuration for merge output format
|
||||||
|
const userConfig = getUserYtDlpConfig(url);
|
||||||
|
const mergeOutputFormat = userConfig.mergeOutputFormat || "mp4";
|
||||||
|
|
||||||
// Create a safe base filename (without extension)
|
// Create a safe base filename (without extension)
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
const safeBaseFilename = `video_${timestamp}`;
|
const safeBaseFilename = `video_${timestamp}`;
|
||||||
|
|
||||||
// Add extensions for video and thumbnail
|
// Add extensions for video and thumbnail (use user's format preference)
|
||||||
const videoFilename = `${safeBaseFilename}.mp4`;
|
const videoFilename = `${safeBaseFilename}.${mergeOutputFormat}`;
|
||||||
const thumbnailFilename = `${safeBaseFilename}.jpg`;
|
const thumbnailFilename = `${safeBaseFilename}.jpg`;
|
||||||
|
|
||||||
// Set full paths for video and thumbnail
|
// Set full paths for video and thumbnail
|
||||||
@@ -926,7 +939,7 @@ export class BilibiliDownloader {
|
|||||||
videoAuthor,
|
videoAuthor,
|
||||||
videoDate
|
videoDate
|
||||||
);
|
);
|
||||||
const newVideoFilename = `${newSafeBaseFilename}.mp4`;
|
const newVideoFilename = `${newSafeBaseFilename}.${mergeOutputFormat}`;
|
||||||
const newThumbnailFilename = `${newSafeBaseFilename}.jpg`;
|
const newThumbnailFilename = `${newSafeBaseFilename}.jpg`;
|
||||||
|
|
||||||
// Rename the files
|
// Rename the files
|
||||||
|
|||||||
@@ -321,8 +321,8 @@ export class YtDlpDownloader {
|
|||||||
const newVideoPath = path.join(VIDEOS_DIR, finalVideoFilename);
|
const newVideoPath = path.join(VIDEOS_DIR, finalVideoFilename);
|
||||||
const newThumbnailPath = path.join(IMAGES_DIR, finalThumbnailFilename);
|
const newThumbnailPath = path.join(IMAGES_DIR, finalThumbnailFilename);
|
||||||
|
|
||||||
// Download the video
|
// Note: newVideoPath will be updated below based on merge output format
|
||||||
console.log("Downloading video to:", newVideoPath);
|
console.log("Preparing video download path:", newVideoPath);
|
||||||
|
|
||||||
if (downloadId) {
|
if (downloadId) {
|
||||||
storageService.updateActiveDownload(downloadId, {
|
storageService.updateActiveDownload(downloadId, {
|
||||||
@@ -348,32 +348,55 @@ export class YtDlpDownloader {
|
|||||||
console.log("Using user-specified format:", userFormat);
|
console.log("Using user-specified format:", userFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare base flags from user config (excluding certain overridden options)
|
// Prepare base flags from user config (excluding output options we manage)
|
||||||
const {
|
const {
|
||||||
output: _output, // Ignore user output template (we manage this)
|
output: _output, // Ignore user output template (we manage this)
|
||||||
o: _o,
|
o: _o,
|
||||||
writeSubs: _writeSubs, // We always enable subtitles
|
|
||||||
writeAutoSubs: _writeAutoSubs,
|
|
||||||
convertSubs: _convertSubs,
|
|
||||||
f: _f, // Format is handled specially above
|
f: _f, // Format is handled specially above
|
||||||
format: _format,
|
format: _format,
|
||||||
S: userFormatSort, // Format sort is handled specially
|
S: userFormatSort, // Format sort is handled specially
|
||||||
formatSort: userFormatSort2,
|
formatSort: userFormatSort2,
|
||||||
|
// Extract user subtitle preferences (use them if provided)
|
||||||
|
writeSubs: userWriteSubs,
|
||||||
|
writeAutoSubs: userWriteAutoSubs,
|
||||||
|
convertSubs: userConvertSubs,
|
||||||
|
// Extract user merge output format (use it if provided)
|
||||||
|
mergeOutputFormat: userMergeOutputFormat,
|
||||||
...safeUserConfig
|
...safeUserConfig
|
||||||
} = userConfig;
|
} = userConfig;
|
||||||
|
|
||||||
// Get format sort option if user specified it
|
// Get format sort option if user specified it
|
||||||
const formatSortValue = userFormatSort || userFormatSort2;
|
const formatSortValue = userFormatSort || userFormatSort2;
|
||||||
|
|
||||||
// Prepare flags - user config first, then our required overrides
|
// Determine merge output format: use user's choice or default to mp4
|
||||||
|
const mergeOutputFormat = userMergeOutputFormat || "mp4";
|
||||||
|
|
||||||
|
// Update the video path to use the correct extension based on merge format
|
||||||
|
const videoExtension = mergeOutputFormat;
|
||||||
|
const newVideoPathWithFormat = newVideoPath.replace(
|
||||||
|
/\.mp4$/,
|
||||||
|
`.${videoExtension}`
|
||||||
|
);
|
||||||
|
finalVideoFilename = finalVideoFilename.replace(
|
||||||
|
/\.mp4$/,
|
||||||
|
`.${videoExtension}`
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Using merge output format: ${mergeOutputFormat}, downloading to: ${newVideoPathWithFormat}`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Prepare flags - defaults first, then user config to allow overrides
|
||||||
const flags: Record<string, any> = {
|
const flags: Record<string, any> = {
|
||||||
...safeUserConfig, // Apply user config first
|
...safeUserConfig, // Apply user config
|
||||||
output: newVideoPath, // Always use our output path
|
output: newVideoPathWithFormat, // Always use our output path with correct extension
|
||||||
format: defaultFormat,
|
format: defaultFormat,
|
||||||
mergeOutputFormat: "mp4",
|
// Use user preferences if provided, otherwise use defaults
|
||||||
writeSubs: true,
|
mergeOutputFormat: mergeOutputFormat,
|
||||||
writeAutoSubs: true,
|
writeSubs: userWriteSubs !== undefined ? userWriteSubs : true,
|
||||||
convertSubs: "vtt",
|
writeAutoSubs:
|
||||||
|
userWriteAutoSubs !== undefined ? userWriteAutoSubs : true,
|
||||||
|
convertSubs: userConvertSubs !== undefined ? userConvertSubs : "vtt",
|
||||||
// Only add PO token provider if configured
|
// Only add PO token provider if configured
|
||||||
...(PROVIDER_SCRIPT
|
...(PROVIDER_SCRIPT
|
||||||
? {
|
? {
|
||||||
@@ -427,7 +450,7 @@ export class YtDlpDownloader {
|
|||||||
|
|
||||||
// Clean up partial files
|
// Clean up partial files
|
||||||
console.log("Cleaning up partial files...");
|
console.log("Cleaning up partial files...");
|
||||||
cleanupPartialVideoFiles(newVideoPath);
|
cleanupPartialVideoFiles(newVideoPathWithFormat);
|
||||||
cleanupPartialVideoFiles(newThumbnailPath);
|
cleanupPartialVideoFiles(newThumbnailPath);
|
||||||
cleanupSubtitleFiles(newSafeBaseFilename);
|
cleanupSubtitleFiles(newSafeBaseFilename);
|
||||||
});
|
});
|
||||||
@@ -487,7 +510,7 @@ export class YtDlpDownloader {
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (isCancellationError(error)) {
|
if (isCancellationError(error)) {
|
||||||
console.log("Download was cancelled");
|
console.log("Download was cancelled");
|
||||||
cleanupPartialVideoFiles(newVideoPath);
|
cleanupPartialVideoFiles(newVideoPathWithFormat);
|
||||||
cleanupSubtitleFiles(newSafeBaseFilename);
|
cleanupSubtitleFiles(newSafeBaseFilename);
|
||||||
throw DownloadCancelledError.create();
|
throw DownloadCancelledError.create();
|
||||||
}
|
}
|
||||||
@@ -501,7 +524,7 @@ export class YtDlpDownloader {
|
|||||||
|
|
||||||
if (isSubtitleError) {
|
if (isSubtitleError) {
|
||||||
// Check if video file was successfully downloaded
|
// Check if video file was successfully downloaded
|
||||||
if (fs.existsSync(newVideoPath)) {
|
if (fs.existsSync(newVideoPathWithFormat)) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Subtitle download failed, but video was downloaded successfully. Continuing...",
|
"Subtitle download failed, but video was downloaded successfully. Continuing...",
|
||||||
error.message
|
error.message
|
||||||
@@ -524,7 +547,7 @@ export class YtDlpDownloader {
|
|||||||
// Check if download was cancelled (it might have been removed from active downloads)
|
// Check if download was cancelled (it might have been removed from active downloads)
|
||||||
if (!isDownloadActive(downloadId)) {
|
if (!isDownloadActive(downloadId)) {
|
||||||
console.log("Download was cancelled (no longer in active downloads)");
|
console.log("Download was cancelled (no longer in active downloads)");
|
||||||
cleanupPartialVideoFiles(newVideoPath);
|
cleanupPartialVideoFiles(newVideoPathWithFormat);
|
||||||
cleanupSubtitleFiles(newSafeBaseFilename);
|
cleanupSubtitleFiles(newSafeBaseFilename);
|
||||||
throw DownloadCancelledError.create();
|
throw DownloadCancelledError.create();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user