1
1
mirror of https://github.com/neosubhamoy/neodlp.git synced 2026-02-04 14:12:22 +05:30

feat: added support for embedding auto-generated subtitles #10

This commit is contained in:
2026-01-04 20:42:29 +05:30
Verified
parent da806b21e9
commit 01f4e96101
6 changed files with 29 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2025 Subhamoy Biswas Copyright (c) 2025-2026 Subhamoy Biswas
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -15,7 +15,7 @@ export default function Footer() {
{isSettingsPage ? ( {isSettingsPage ? (
<div className="flex items-center justify-between p-4 border-t border-border"> <div className="flex items-center justify-between p-4 border-t border-border">
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<span className="text-sm">{config.appName} v{appVersion} - &copy; {new Date().getFullYear()} &nbsp;|&nbsp; <a href={'https://github.com/' + config.appRepo + '/blob/main/LICENSE'} target="_blank">MIT License</a></span> <span className="text-sm">{config.appName} v{appVersion} &copy; 2025 - {new Date().getFullYear()} &nbsp;|&nbsp; <a href={'https://github.com/' + config.appRepo + '/blob/main/LICENSE'} target="_blank">MIT License</a></span>
<span className="text-xs text-muted-foreground">Proudly Made with <Heart className="inline size-3 mb-0.5 fill-primary stroke-primary"/> in India <IndianFlagLogo className="inline size-full w-4 ml-0.5 mb-[0.1rem]" /></span> <span className="text-xs text-muted-foreground">Proudly Made with <Heart className="inline size-3 mb-0.5 fill-primary stroke-primary"/> in India <IndianFlagLogo className="inline size-full w-4 ml-0.5 mb-[0.1rem]" /></span>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">

View File

@@ -1395,7 +1395,7 @@ function AppInfoSettings() {
<p className="text-xs text-muted-foreground mb-3">License and usage terms of NeoDLP</p> <p className="text-xs text-muted-foreground mb-3">License and usage terms of NeoDLP</p>
<div className="license"> <div className="license">
<p className="text-sm mb-3">NeoDLP is a Fully Open-Source Software Licensed under the MIT license. Anyone can view, modify, use (personal and commercial) or distribute it's sources without any extra permission (Just include the LICENSE file :)</p> <p className="text-sm mb-3">NeoDLP is a Fully Open-Source Software Licensed under the MIT license. Anyone can view, modify, use (personal and commercial) or distribute it's sources without any extra permission (Just include the LICENSE file :)</p>
<p className="text-sm mb-3"><TriangleAlert className="size-4 stroke-primary inline mb-1 mr-0.5" /> DISCLAIMER: NeoDLP facilitates Downloading from various Online Platforms which have their own Policies and Terms of Use, Downloading and using Copyrighted Content from these Sites for Commercial pourposes are not allowed by most Platforms without prior Permission (We absolutely do not promote this kinds of activity), You should use the downloaded content wisely and solely at your own responsibility.</p> <p className="text-sm mb-3"><TriangleAlert className="size-4 stroke-primary inline mb-1 mr-0.5" /> DISCLAIMER: NeoDLP facilitates downloading from various Online Platforms with different Policies and Terms of Use which Users must follow. We strictly do not promote any unauthorized downloading of copyrighted content and content piracy. NeoDLP is only made for downloading content that the user holds the copyright to or has the authority for. Users must use the downloaded content wisely and solely at their own legal responsibility. The developer is not responsible for any action taken by the user, and takes zero direct or indirect liability for that matter.</p>
<span className="flex items-center gap-4 flex-wrap"> <span className="flex items-center gap-4 flex-wrap">
<Button className="px-4" variant="outline" size="sm" asChild> <Button className="px-4" variant="outline" size="sm" asChild>
<a href={'https://github.com/' + config.appRepo + '/blob/main/LICENSE'} target="_blank" > <a href={'https://github.com/' + config.appRepo + '/blob/main/LICENSE'} target="_blank" >

View File

@@ -103,7 +103,11 @@ export default function useDownloader() {
try { try {
const args = [url, '--dump-single-json', '--no-warnings']; const args = [url, '--dump-single-json', '--no-warnings'];
if (formatId) args.push('--format', formatId); if (formatId) args.push('--format', formatId);
if (selectedSubtitles) args.push('--embed-subs', '--sub-lang', selectedSubtitles); if (selectedSubtitles) {
const isAutoSub = selectedSubtitles.split(',').some(lang => lang.endsWith('-orig'));
if (isAutoSub) args.push('--write-auto-sub');
args.push('--embed-subs', '--sub-lang', selectedSubtitles);
}
if (playlistIndex) args.push('--playlist-items', playlistIndex); if (playlistIndex) args.push('--playlist-items', playlistIndex);
if (PREFER_VIDEO_OVER_PLAYLIST && !playlistIndex) args.push('--no-playlist'); if (PREFER_VIDEO_OVER_PLAYLIST && !playlistIndex) args.push('--no-playlist');
if (STRICT_DOWNLOADABILITY_CHECK && !formatId) args.push('--check-all-formats'); if (STRICT_DOWNLOADABILITY_CHECK && !formatId) args.push('--check-all-formats');
@@ -298,6 +302,8 @@ export default function useDownloader() {
} }
if (selectedSubtitles) { if (selectedSubtitles) {
const isAutoSub = selectedSubtitles.split(',').some(lang => lang.endsWith('-orig'));
if (isAutoSub) args.push('--write-auto-sub');
args.push('--embed-subs', '--sub-lang', selectedSubtitles); args.push('--embed-subs', '--sub-lang', selectedSubtitles);
} }

View File

@@ -130,10 +130,21 @@ export default function DownloaderPage() {
})(); })();
const subtitles = videoMetadata?._type === 'video' ? (videoMetadata?.subtitles || {}) : videoMetadata?._type === 'playlist' ? (videoMetadata?.entries[Number(selectedPlaylistVideoIndex) - 1].subtitles || {}) : {}; const subtitles = videoMetadata?._type === 'video' ? (videoMetadata?.subtitles || {}) : videoMetadata?._type === 'playlist' ? (videoMetadata?.entries[Number(selectedPlaylistVideoIndex) - 1].subtitles || {}) : {};
const subtitleLanguages = Object.keys(subtitles).map(langCode => ({ const filteredSubtitles = Object.fromEntries(Object.entries(subtitles).filter(([key]) => key !== 'live_chat'));
const autoSubtitles = videoMetadata?._type === 'video' ? (videoMetadata?.automatic_captions || {}) : videoMetadata?._type === 'playlist' ? (videoMetadata?.entries[Number(selectedPlaylistVideoIndex) - 1].automatic_captions || {}) : {};
const originalAutoSubtitles = Object.fromEntries(Object.entries(autoSubtitles).filter(([key]) => key.endsWith('-orig')));
const subtitleLanguages = Object.keys(filteredSubtitles).map(langCode => ({
code: langCode, code: langCode,
lang: subtitles[langCode][0].name || langCode lang: filteredSubtitles[langCode][0].name || langCode
})); }));
const autoSubtitleLanguages = Object.keys(originalAutoSubtitles).map(langCode => ({
code: langCode,
lang: originalAutoSubtitles[langCode][0].name + ' [auto-generated]' || langCode + ' [auto-generated]'
}));
const allSubtitleLanguages = Array.from(new Set([...subtitleLanguages, ...autoSubtitleLanguages].map(lang => lang.code))).map(code => {
return [...subtitleLanguages, ...autoSubtitleLanguages].find(lang => lang.code === code)!;
});
const searchForm = useForm<z.infer<typeof searchFormSchema>>({ const searchForm = useForm<z.infer<typeof searchFormSchema>>({
resolver: zodResolver(searchFormSchema), resolver: zodResolver(searchFormSchema),
@@ -338,7 +349,7 @@ export default function DownloaderPage() {
videoOnlyFormats={videoOnlyFormats} videoOnlyFormats={videoOnlyFormats}
combinedFormats={combinedFormats} combinedFormats={combinedFormats}
qualityPresetFormats={qualityPresetFormats} qualityPresetFormats={qualityPresetFormats}
subtitleLanguages={subtitleLanguages} subtitleLanguages={allSubtitleLanguages}
/> />
)} )}
{!isMetadataLoading && videoMetadata && videoMetadata._type === 'playlist' && ( {!isMetadataLoading && videoMetadata && videoMetadata._type === 'playlist' && (
@@ -348,7 +359,7 @@ export default function DownloaderPage() {
videoOnlyFormats={videoOnlyFormats} videoOnlyFormats={videoOnlyFormats}
combinedFormats={combinedFormats} combinedFormats={combinedFormats}
qualityPresetFormats={qualityPresetFormats} qualityPresetFormats={qualityPresetFormats}
subtitleLanguages={subtitleLanguages} subtitleLanguages={allSubtitleLanguages}
/> />
)} )}
{!isMetadataLoading && videoMetadata && selectedDownloadFormat && ( {!isMetadataLoading && videoMetadata && selectedDownloadFormat && (

View File

@@ -31,6 +31,9 @@ export interface RawVideoInfo {
subtitles: { subtitles: {
[subtitle_id: string]: VideoSubtitle[]; [subtitle_id: string]: VideoSubtitle[];
}; };
automatic_captions: {
[subtitle_id: string]: VideoSubtitle[];
};
formats: VideoFormat[]; formats: VideoFormat[];
requested_downloads: VideoFormat[]; requested_downloads: VideoFormat[];
requested_subtitles: { requested_subtitles: {