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:
2
LICENSE
2
LICENSE
@@ -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
|
||||||
|
|||||||
@@ -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} - © {new Date().getFullYear()} | <a href={'https://github.com/' + config.appRepo + '/blob/main/LICENSE'} target="_blank">MIT License</a></span>
|
<span className="text-sm">{config.appName} v{appVersion} © 2025 - {new Date().getFullYear()} | <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">
|
||||||
|
|||||||
@@ -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" >
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 && (
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user