From cbcf50a84921be91aa39be37bf45398b79e18759 Mon Sep 17 00:00:00 2001 From: JellyBrick Date: Sat, 14 Oct 2023 01:17:06 +0900 Subject: [PATCH 1/3] feat: Added support for audio format auto-detection --- config/defaults.ts | 6 +- config/store.ts | 22 +++++++ plugins/downloader/back.ts | 123 ++++++++++++++---------------------- plugins/downloader/menu.ts | 9 +-- plugins/downloader/types.ts | 116 ++++++++++++++++++++++++++++++++++ plugins/downloader/utils.ts | 11 +--- 6 files changed, 195 insertions(+), 92 deletions(-) create mode 100644 plugins/downloader/types.ts diff --git a/config/defaults.ts b/config/defaults.ts index e8a3a70425..1240057d7d 100644 --- a/config/defaults.ts +++ b/config/defaults.ts @@ -1,5 +1,7 @@ import { blockers } from '../plugins/adblocker/blocker-types'; +import { DefaultPresetList } from '../plugins/downloader/types'; + export interface WindowSizeConfig { width: number; height: number; @@ -111,9 +113,9 @@ const defaultConfig = { }, 'downloader': { enabled: false, - ffmpegArgs: ['-b:a', '256k'], // E.g. ["-b:a", "192k"] for an audio bitrate of 192kb/s downloadFolder: undefined as string | undefined, // Custom download folder (absolute path) - preset: 'mp3', + selectedPreset: 'mp3 (256kbps)', // Selected preset + customPresetSetting: DefaultPresetList['Custom'], // Presets skipExisting: false, playlistMaxItems: undefined as number | undefined, }, diff --git a/config/store.ts b/config/store.ts index f5fdac9ddf..d5cc71084e 100644 --- a/config/store.ts +++ b/config/store.ts @@ -3,6 +3,8 @@ import Conf from 'conf'; import defaults from './defaults'; +import type { Preset } from '../plugins/downloader/types'; + const setDefaultPluginOptions = (store: Conf>, plugin: keyof typeof defaults.plugins) => { if (!store.get(`plugins.${plugin}`)) { store.set(`plugins.${plugin}`, defaults.plugins[plugin]); @@ -10,6 +12,26 @@ const setDefaultPluginOptions = (store: Conf>, plugin: k }; const migrations = { + '>=2.1.0'(store: Conf>) { + const originalPreset = store.get('plugins.downloader.preset') as string | undefined; + if (originalPreset) { + if (originalPreset !== 'opus') { + store.set('plugins.downloader.selectedPreset', 'Custom'); + store.set('plugins.downloader.customPresetSetting', { + extension: 'mp3', + ffmpegArgs: store.get('plugins.downloader.ffmpegArgs') as string[] ?? [], + } satisfies Preset); + } else { + store.set('plugins.downloader.selectedPreset', 'Source'); + store.set('plugins.downloader.customPresetSetting', { + extension: null, + ffmpegArgs: store.get('plugins.downloader.ffmpegArgs') as string[] ?? [], + } satisfies Preset); + } + store.delete('plugins.downloader.preset'); + store.delete('plugins.downloader.ffmpegArgs'); + } + }, '>=1.20.0'(store: Conf>) { setDefaultPluginOptions(store, 'visualizer'); diff --git a/plugins/downloader/back.ts b/plugins/downloader/back.ts index 69a3d173b4..874d105f64 100644 --- a/plugins/downloader/back.ts +++ b/plugins/downloader/back.ts @@ -8,12 +8,11 @@ import is from 'electron-is'; import filenamify from 'filenamify'; import { Mutex } from 'async-mutex'; import { createFFmpeg } from '@ffmpeg.wasm/main'; - import NodeID3, { TagConstants } from 'node-id3'; -import { cropMaxWidth, getFolder, presets, sendFeedback as sendFeedback_, setBadge } from './utils'; - +import { cropMaxWidth, getFolder, sendFeedback as sendFeedback_, setBadge } from './utils'; import config from './config'; +import { YoutubeFormatList, type Preset, DefaultPresetList } from './types'; import style from './style.css'; @@ -221,13 +220,32 @@ async function downloadSongUnsafe( ); } - const preset = config.get('preset') ?? 'mp3'; - let presetSetting: { extension: string; ffmpegArgs: string[] } | null = null; - if (preset === 'opus') { - presetSetting = presets[preset]; + const selectedPreset = config.get('selectedPreset') ?? 'mp3 (256kbps)'; + let presetSetting: Preset; + if (selectedPreset === 'Custom') { + presetSetting = config.get('customPresetSetting') ?? DefaultPresetList['Custom']; + } else if (selectedPreset === 'Source') { + presetSetting = DefaultPresetList['Source']; + } else { + presetSetting = DefaultPresetList['mp3 (256kbps)']; } - let filename = filenamify(`${name}.${presetSetting?.extension ?? 'mp3'}`, { + const downloadOptions: FormatOptions = { + type: 'audio', // Audio, video or video+audio + quality: 'best', // Best, bestefficiency, 144p, 240p, 480p, 720p and so on. + format: 'any', // Media container format + }; + + const format = info.chooseFormat(downloadOptions); + + let targetFileExtension: string; + if (!presetSetting?.extension) { + targetFileExtension = YoutubeFormatList.find((it) => it.itag === format.itag)?.container ?? 'mp3'; + } else { + targetFileExtension = presetSetting?.extension ?? 'mp3'; + } + + let filename = filenamify(`${name}.${targetFileExtension}`, { replacement: '_', maxLength: 255, }); @@ -241,13 +259,6 @@ async function downloadSongUnsafe( return; } - const downloadOptions: FormatOptions = { - type: 'audio', // Audio, video or video+audio - quality: 'best', // Best, bestefficiency, 144p, 240p, 480p, 720p and so on. - format: 'any', // Media container format - }; - - const format = info.chooseFormat(downloadOptions); const stream = await info.download(downloadOptions); console.info( @@ -260,39 +271,20 @@ async function downloadSongUnsafe( mkdirSync(dir); } - const ffmpegArgs = config.get('ffmpegArgs'); - - if (presetSetting && presetSetting?.extension !== 'mp3') { - const file = createWriteStream(filePath); - let downloaded = 0; - const total: number = format.content_length ?? 1; - - for await (const chunk of iterableStream) { - downloaded += chunk.length; - const ratio = downloaded / total; - const progress = Math.floor(ratio * 100); - sendFeedback(`Download: ${progress}%`, ratio); - increasePlaylistProgress(ratio); - file.write(chunk); - } + const fileBuffer = await iterableStreamToTargetFile( + iterableStream, + targetFileExtension, + metadata, + presetSetting?.ffmpegArgs ?? [], + format.content_length ?? 0, + sendFeedback, + increasePlaylistProgress, + ); - await ffmpegWriteTags( - filePath, - metadata, - presetSetting.ffmpegArgs, - ffmpegArgs, - ); - sendFeedback(null, -1); - } else { - const fileBuffer = await iterableStreamToMP3( - iterableStream, - metadata, - ffmpegArgs, - format.content_length ?? 0, - sendFeedback, - increasePlaylistProgress, - ); - if (fileBuffer) { + if (fileBuffer) { + if (targetFileExtension !== 'mp3') { + createWriteStream(filePath).write(fileBuffer); + } else { const buffer = await writeID3(Buffer.from(fileBuffer), metadata, sendFeedback); if (buffer) { writeFileSync(filePath, buffer); @@ -304,10 +296,11 @@ async function downloadSongUnsafe( console.info(`Done: "${filePath}"`); } -async function iterableStreamToMP3( +async function iterableStreamToTargetFile( stream: AsyncGenerator, + extension: string, metadata: CustomSongInfo, - ffmpegArgs: string[], + presetFfmpegArgs: string[], contentLength: number, sendFeedback: (str: string, value?: number) => void, increasePlaylistProgress: (value: number) => void = () => { @@ -347,13 +340,14 @@ async function iterableStreamToMP3( increasePlaylistProgress(0.15 + (ratio * 0.85)); }); + const safeVideoNameWithExtension = `${safeVideoName}.${extension}`; try { await ffmpeg.run( '-i', safeVideoName, - ...ffmpegArgs, + ...presetFfmpegArgs, ...getFFmpegMetadataArgs(metadata), - `${safeVideoName}.mp3`, + safeVideoNameWithExtension, ); } finally { ffmpeg.FS('unlink', safeVideoName); @@ -362,9 +356,9 @@ async function iterableStreamToMP3( sendFeedback('Saving…'); try { - return ffmpeg.FS('readFile', `${safeVideoName}.mp3`); + return ffmpeg.FS('readFile', safeVideoNameWithExtension); } finally { - ffmpeg.FS('unlink', `${safeVideoName}.mp3`); + ffmpeg.FS('unlink', safeVideoNameWithExtension); } } catch (error: unknown) { sendError(error as Error, safeVideoName); @@ -544,29 +538,6 @@ export async function downloadPlaylist(givenUrl?: string | URL) { } } -async function ffmpegWriteTags(filePath: string, metadata: CustomSongInfo, presetFFmpegArgs: string[] = [], ffmpegArgs: string[] = []) { - const releaseFFmpegMutex = await ffmpegMutex.acquire(); - - try { - if (!ffmpeg.isLoaded()) { - await ffmpeg.load(); - } - - await ffmpeg.run( - '-i', - filePath, - ...getFFmpegMetadataArgs(metadata), - ...presetFFmpegArgs, - ...ffmpegArgs, - filePath, - ); - } catch (error: unknown) { - sendError(error as Error); - } finally { - releaseFFmpegMutex(); - } -} - function getFFmpegMetadataArgs(metadata: CustomSongInfo) { if (!metadata) { return []; diff --git a/plugins/downloader/menu.ts b/plugins/downloader/menu.ts index c49a638986..d96ded1532 100644 --- a/plugins/downloader/menu.ts +++ b/plugins/downloader/menu.ts @@ -1,7 +1,8 @@ import { dialog } from 'electron'; import { downloadPlaylist } from './back'; -import { defaultMenuDownloadLabel, getFolder, presets } from './utils'; +import { defaultMenuDownloadLabel, getFolder } from './utils'; +import { DefaultPresetList } from './types'; import config from './config'; import { MenuTemplate } from '../../menu'; @@ -25,12 +26,12 @@ export default (): MenuTemplate => [ }, { label: 'Presets', - submenu: Object.keys(presets).map((preset) => ({ + submenu: Object.keys(DefaultPresetList).map((preset) => ({ label: preset, type: 'radio', - checked: config.get('preset') === preset, + checked: config.get('selectedPreset') === preset, click() { - config.set('preset', preset); + config.set('selectedPreset', preset); }, })), }, diff --git a/plugins/downloader/types.ts b/plugins/downloader/types.ts new file mode 100644 index 0000000000..8c5cee8fc6 --- /dev/null +++ b/plugins/downloader/types.ts @@ -0,0 +1,116 @@ +export interface Preset { + extension?: string | null; + ffmpegArgs: string[]; +} + +// Presets for FFmpeg +export const DefaultPresetList: Record = { + 'mp3 (256kbps)': { + extension: 'mp3', + ffmpegArgs: ['-b:a', '256k'], + }, + 'Source': { + extension: undefined, + ffmpegArgs: ['-acodec', 'copy'], + }, + 'Custom': { + extension: null, + ffmpegArgs: ['-b:a', '320k'], + } +}; + +export interface YouTubeFormat { + itag: number; + container: string; + content: string; + resolution: string; + bitrate: string; + range: string; + vrOr3D: string; +} + +// converted from https://gist.github.com/sidneys/7095afe4da4ae58694d128b1034e01e2#file-youtube_format_code_itag_list-md +export const YoutubeFormatList: YouTubeFormat[] = [ + { itag: 5, container: 'flv', content: 'audio/video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 6, container: 'flv', content: 'audio/video', resolution: '270p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 17, container: '3gp', content: 'audio/video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 18, container: 'mp4', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 22, container: 'mp4', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 34, container: 'flv', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 35, container: 'flv', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 36, container: '3gp', content: 'audio/video', resolution: '180p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 37, container: 'mp4', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 38, container: 'mp4', content: 'audio/video', resolution: '3072p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 43, container: 'webm', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 44, container: 'webm', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 45, container: 'webm', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 46, container: 'webm', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 82, container: 'mp4', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 83, container: 'mp4', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 84, container: 'mp4', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 85, container: 'mp4', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 91, container: 'hls', content: 'audio/video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 92, container: 'hls', content: 'audio/video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 93, container: 'hls', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 94, container: 'hls', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 95, container: 'hls', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 96, container: 'hls', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '-' }, + { itag: 100, container: 'webm', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 101, container: 'webm', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 102, container: 'webm', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '3D' }, + { itag: 132, container: 'hls', content: 'audio/video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 133, container: 'mp4', content: 'video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 134, container: 'mp4', content: 'video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 135, container: 'mp4', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 136, container: 'mp4', content: 'video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 137, container: 'mp4', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 138, container: 'mp4', content: 'video', resolution: '2160p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 139, container: 'm4a', content: 'audio', resolution: '-', bitrate: '48k', range: '-', vrOr3D: '' }, + { itag: 140, container: 'm4a', content: 'audio', resolution: '-', bitrate: '128k', range: '-', vrOr3D: '' }, + { itag: 141, container: 'm4a', content: 'audio', resolution: '-', bitrate: '256k', range: '-', vrOr3D: '' }, + { itag: 151, container: 'hls', content: 'audio/video', resolution: '72p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 160, container: 'mp4', content: 'video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 167, container: 'webm', content: 'video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 168, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 169, container: 'webm', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 171, container: 'webm', content: 'audio', resolution: '-', bitrate: '128k', range: '-', vrOr3D: '' }, + { itag: 218, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 219, container: 'webm', content: 'video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 242, container: 'webm', content: 'video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 243, container: 'webm', content: 'video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 244, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 245, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 246, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 247, container: 'webm', content: 'video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 248, container: 'webm', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 249, container: 'webm', content: 'audio', resolution: '-', bitrate: '50k', range: '-', vrOr3D: '' }, + { itag: 250, container: 'webm', content: 'audio', resolution: '-', bitrate: '70k', range: '-', vrOr3D: '' }, + { itag: 251, container: 'webm', content: 'audio', resolution: '-', bitrate: '160k', range: '-', vrOr3D: '' }, + { itag: 264, container: 'mp4', content: 'video', resolution: '1440p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 266, container: 'mp4', content: 'video', resolution: '2160p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 271, container: 'webm', content: 'video', resolution: '1440p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 272, container: 'webm', content: 'video', resolution: '4320p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 278, container: 'webm', content: 'video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 298, container: 'mp4', content: 'video', resolution: '720p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 299, container: 'mp4', content: 'video', resolution: '1080p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 302, container: 'webm', content: 'video', resolution: '720p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 303, container: 'webm', content: 'video', resolution: '1080p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 308, container: 'webm', content: 'video', resolution: '1440p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 313, container: 'webm', content: 'video', resolution: '2160p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 315, container: 'webm', content: 'video', resolution: '2160p60', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 330, container: 'webm', content: 'video', resolution: '144p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 331, container: 'webm', content: 'video', resolution: '240p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 332, container: 'webm', content: 'video', resolution: '360p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 333, container: 'webm', content: 'video', resolution: '480p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 334, container: 'webm', content: 'video', resolution: '720p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 335, container: 'webm', content: 'video', resolution: '1080p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 336, container: 'webm', content: 'video', resolution: '1440p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 337, container: 'webm', content: 'video', resolution: '2160p60', bitrate: '-', range: 'hdr', vrOr3D: '' }, + { itag: 272, container: 'webm', content: 'video', resolution: '2880p/4320p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 399, container: 'mp4', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 400, container: 'mp4', content: 'video', resolution: '1440p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 401, container: 'mp4', content: 'video', resolution: '2160p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 402, container: 'mp4', content: 'video', resolution: '2880p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 571, container: 'mp4', content: 'video', resolution: '3840p', bitrate: '-', range: '-', vrOr3D: '' }, + { itag: 702, container: 'mp4', content: 'video', resolution: '3840p', bitrate: '-', range: '-', vrOr3D: '' }, +]; diff --git a/plugins/downloader/utils.ts b/plugins/downloader/utils.ts index 7de1f09648..feabc52a47 100644 --- a/plugins/downloader/utils.ts +++ b/plugins/downloader/utils.ts @@ -10,7 +10,7 @@ export const sendFeedback = (win: BrowserWindow, message?: unknown) => { export const cropMaxWidth = (image: Electron.NativeImage) => { const imageSize = image.getSize(); - // Standart youtube artwork width with margins from both sides is 280 + 720 + 280 + // Standart YouTube artwork width with margins from both sides is 280 + 720 + 280 if (imageSize.width === 1280 && imageSize.height === 720) { return image.crop({ x: 280, @@ -23,15 +23,6 @@ export const cropMaxWidth = (image: Electron.NativeImage) => { return image; }; -// Presets for FFmpeg -export const presets = { - 'None (defaults to mp3)': undefined, - 'opus': { - extension: 'opus', - ffmpegArgs: ['-acodec', 'libopus'], - }, -}; - export const setBadge = (n: number) => { if (is.linux() || is.macOS()) { app.setBadgeCount(n); From 091e9271d6f710bb8eb82195af2c47a4589241d9 Mon Sep 17 00:00:00 2001 From: JellyBrick Date: Sat, 14 Oct 2023 03:06:45 +0900 Subject: [PATCH 2/3] chore: change default variable --- config/defaults.ts | 2 +- config/store.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/defaults.ts b/config/defaults.ts index 1240057d7d..dc07633c61 100644 --- a/config/defaults.ts +++ b/config/defaults.ts @@ -115,7 +115,7 @@ const defaultConfig = { enabled: false, downloadFolder: undefined as string | undefined, // Custom download folder (absolute path) selectedPreset: 'mp3 (256kbps)', // Selected preset - customPresetSetting: DefaultPresetList['Custom'], // Presets + customPresetSetting: DefaultPresetList['mp3 (256kbps)'], // Presets skipExisting: false, playlistMaxItems: undefined as number | undefined, }, diff --git a/config/store.ts b/config/store.ts index d5cc71084e..222ffdd876 100644 --- a/config/store.ts +++ b/config/store.ts @@ -3,7 +3,7 @@ import Conf from 'conf'; import defaults from './defaults'; -import type { Preset } from '../plugins/downloader/types'; +import { DefaultPresetList, type Preset } from '../plugins/downloader/types'; const setDefaultPluginOptions = (store: Conf>, plugin: keyof typeof defaults.plugins) => { if (!store.get(`plugins.${plugin}`)) { @@ -19,7 +19,7 @@ const migrations = { store.set('plugins.downloader.selectedPreset', 'Custom'); store.set('plugins.downloader.customPresetSetting', { extension: 'mp3', - ffmpegArgs: store.get('plugins.downloader.ffmpegArgs') as string[] ?? [], + ffmpegArgs: store.get('plugins.downloader.ffmpegArgs') as string[] ?? DefaultPresetList['mp3 (256kbps)'].ffmpegArgs, } satisfies Preset); } else { store.set('plugins.downloader.selectedPreset', 'Source'); From df44333167df042b1b1037e31518d81b0220c47f Mon Sep 17 00:00:00 2001 From: JellyBrick Date: Sat, 14 Oct 2023 03:39:31 +0900 Subject: [PATCH 3/3] remove default ffmpegArgs for 'Custom' in DefaultPresetList --- plugins/downloader/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/downloader/types.ts b/plugins/downloader/types.ts index 8c5cee8fc6..175fc015e9 100644 --- a/plugins/downloader/types.ts +++ b/plugins/downloader/types.ts @@ -15,7 +15,7 @@ export const DefaultPresetList: Record = { }, 'Custom': { extension: null, - ffmpegArgs: ['-b:a', '320k'], + ffmpegArgs: [], } };