vidsmith 1.0.0rc1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. vidsmith-1.0.0rc1/.gitignore +85 -0
  2. vidsmith-1.0.0rc1/CHANGELOG.md +36 -0
  3. vidsmith-1.0.0rc1/LICENSE +21 -0
  4. vidsmith-1.0.0rc1/PKG-INFO +327 -0
  5. vidsmith-1.0.0rc1/README.md +282 -0
  6. vidsmith-1.0.0rc1/pyproject.toml +138 -0
  7. vidsmith-1.0.0rc1/src/vidsmith/__init__.py +3 -0
  8. vidsmith-1.0.0rc1/src/vidsmith/cli/__init__.py +0 -0
  9. vidsmith-1.0.0rc1/src/vidsmith/cli/app.py +184 -0
  10. vidsmith-1.0.0rc1/src/vidsmith/cli/commands/__init__.py +0 -0
  11. vidsmith-1.0.0rc1/src/vidsmith/cli/doctor.py +218 -0
  12. vidsmith-1.0.0rc1/src/vidsmith/cli/executor.py +1264 -0
  13. vidsmith-1.0.0rc1/src/vidsmith/cli/menus.py +186 -0
  14. vidsmith-1.0.0rc1/src/vidsmith/cli/output.py +61 -0
  15. vidsmith-1.0.0rc1/src/vidsmith/cli/summary/__init__.py +5 -0
  16. vidsmith-1.0.0rc1/src/vidsmith/cli/summary/builder.py +298 -0
  17. vidsmith-1.0.0rc1/src/vidsmith/cli/summary/model.py +24 -0
  18. vidsmith-1.0.0rc1/src/vidsmith/cli/summary/renderer.py +74 -0
  19. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/__init__.py +33 -0
  20. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/base.py +160 -0
  21. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/chrome.py +138 -0
  22. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/dispatcher.py +176 -0
  23. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/registry.py +70 -0
  24. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/__init__.py +16 -0
  25. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/_base.py +39 -0
  26. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/choice.py +119 -0
  27. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/confirm.py +83 -0
  28. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/multi_select.py +114 -0
  29. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/numeric.py +86 -0
  30. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/text_input.py +86 -0
  31. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/steps/toggle.py +71 -0
  32. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/wizards/__init__.py +13 -0
  33. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/wizards/audio.py +128 -0
  34. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/wizards/playlist.py +104 -0
  35. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/wizards/settings.py +197 -0
  36. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/wizards/subtitles.py +81 -0
  37. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/wizards/transcript.py +104 -0
  38. vidsmith-1.0.0rc1/src/vidsmith/cli/wizard/wizards/video.py +276 -0
  39. vidsmith-1.0.0rc1/src/vidsmith/config/__init__.py +6 -0
  40. vidsmith-1.0.0rc1/src/vidsmith/downloader/__init__.py +31 -0
  41. vidsmith-1.0.0rc1/src/vidsmith/downloader/cleanup.py +172 -0
  42. vidsmith-1.0.0rc1/src/vidsmith/downloader/engine.py +105 -0
  43. vidsmith-1.0.0rc1/src/vidsmith/downloader/job.py +151 -0
  44. vidsmith-1.0.0rc1/src/vidsmith/downloader/manager.py +124 -0
  45. vidsmith-1.0.0rc1/src/vidsmith/downloader/progress.py +77 -0
  46. vidsmith-1.0.0rc1/src/vidsmith/downloader/queue.py +96 -0
  47. vidsmith-1.0.0rc1/src/vidsmith/downloader/validator.py +58 -0
  48. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/__init__.py +20 -0
  49. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/audio.py +57 -0
  50. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/context.py +96 -0
  51. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/file.py +24 -0
  52. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/metadata.py +33 -0
  53. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/models.py +77 -0
  54. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/subtitle.py +101 -0
  55. vidsmith-1.0.0rc1/src/vidsmith/downloader/validators/thumbnail.py +104 -0
  56. vidsmith-1.0.0rc1/src/vidsmith/main.py +86 -0
  57. vidsmith-1.0.0rc1/src/vidsmith/metadata/__init__.py +0 -0
  58. vidsmith-1.0.0rc1/src/vidsmith/metadata/analyzer.py +220 -0
  59. vidsmith-1.0.0rc1/src/vidsmith/models/__init__.py +3 -0
  60. vidsmith-1.0.0rc1/src/vidsmith/models/media.py +66 -0
  61. vidsmith-1.0.0rc1/src/vidsmith/playlist/__init__.py +48 -0
  62. vidsmith-1.0.0rc1/src/vidsmith/playlist/batch.py +142 -0
  63. vidsmith-1.0.0rc1/src/vidsmith/playlist/engine.py +163 -0
  64. vidsmith-1.0.0rc1/src/vidsmith/playlist/exceptions.py +25 -0
  65. vidsmith-1.0.0rc1/src/vidsmith/playlist/models.py +206 -0
  66. vidsmith-1.0.0rc1/src/vidsmith/playlist/queue.py +186 -0
  67. vidsmith-1.0.0rc1/src/vidsmith/processing/__init__.py +37 -0
  68. vidsmith-1.0.0rc1/src/vidsmith/processing/exceptions.py +29 -0
  69. vidsmith-1.0.0rc1/src/vidsmith/processing/ffmpeg.py +314 -0
  70. vidsmith-1.0.0rc1/src/vidsmith/processing/models.py +98 -0
  71. vidsmith-1.0.0rc1/src/vidsmith/processing/processor.py +23 -0
  72. vidsmith-1.0.0rc1/src/vidsmith/providers/__init__.py +40 -0
  73. vidsmith-1.0.0rc1/src/vidsmith/providers/base.py +99 -0
  74. vidsmith-1.0.0rc1/src/vidsmith/providers/capabilities.py +72 -0
  75. vidsmith-1.0.0rc1/src/vidsmith/providers/metadata.py +80 -0
  76. vidsmith-1.0.0rc1/src/vidsmith/providers/results.py +35 -0
  77. vidsmith-1.0.0rc1/src/vidsmith/providers/youtube.py +2018 -0
  78. vidsmith-1.0.0rc1/src/vidsmith/settings/__init__.py +35 -0
  79. vidsmith-1.0.0rc1/src/vidsmith/settings/store.py +193 -0
  80. vidsmith-1.0.0rc1/src/vidsmith/subtitle/__init__.py +151 -0
  81. vidsmith-1.0.0rc1/src/vidsmith/thumbnail/__init__.py +0 -0
  82. vidsmith-1.0.0rc1/src/vidsmith/transcript/__init__.py +44 -0
  83. vidsmith-1.0.0rc1/src/vidsmith/transcript/cleaner.py +97 -0
  84. vidsmith-1.0.0rc1/src/vidsmith/transcript/engine.py +133 -0
  85. vidsmith-1.0.0rc1/src/vidsmith/transcript/exceptions.py +21 -0
  86. vidsmith-1.0.0rc1/src/vidsmith/transcript/json_export.py +31 -0
  87. vidsmith-1.0.0rc1/src/vidsmith/transcript/markdown.py +27 -0
  88. vidsmith-1.0.0rc1/src/vidsmith/transcript/models.py +87 -0
  89. vidsmith-1.0.0rc1/src/vidsmith/transcript/parser.py +178 -0
  90. vidsmith-1.0.0rc1/src/vidsmith/transcript/text.py +35 -0
  91. vidsmith-1.0.0rc1/src/vidsmith/utils/__init__.py +0 -0
  92. vidsmith-1.0.0rc1/src/vidsmith/utils/console.py +22 -0
  93. vidsmith-1.0.0rc1/src/vidsmith/utils/environment.py +157 -0
  94. vidsmith-1.0.0rc1/src/vidsmith/utils/exceptions.py +26 -0
  95. vidsmith-1.0.0rc1/src/vidsmith/utils/logging.py +45 -0
  96. vidsmith-1.0.0rc1/src/vidsmith/utils/validators.py +22 -0
@@ -0,0 +1,85 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ .Python
9
+ build/
10
+ dist/
11
+ downloads/
12
+ out/
13
+ tmp/
14
+ *.egg-info/
15
+ *.egg
16
+ wheels/
17
+ .installed.cfg
18
+
19
+ # Virtual environments
20
+ .venv/
21
+ venv/
22
+ env/
23
+ ENV/
24
+ .env
25
+ .env.*
26
+
27
+ # Test / coverage / caches
28
+ .pytest_cache/
29
+ .mypy_cache/
30
+ .ruff_cache/
31
+ .coverage
32
+ .coverage.*
33
+ htmlcov/
34
+ coverage.xml
35
+ .tox/
36
+ .nox/
37
+
38
+ # Editors / IDEs
39
+ .idea/
40
+ .vscode/
41
+ *.swp
42
+ *.swo
43
+ *~
44
+
45
+ # AI assistant local state
46
+ .claude/
47
+
48
+ # OS noise
49
+ .DS_Store
50
+ Thumbs.db
51
+
52
+ # VidSmith output artifacts (downloaded media should never be committed)
53
+ *.mp4
54
+ *.mkv
55
+ *.webm
56
+ *.m4a
57
+ *.mp3
58
+ *.opus
59
+ *.flac
60
+ *.wav
61
+ *.vtt
62
+ *.srt
63
+ *.webp
64
+ *.part
65
+ *.ytdl
66
+ *.jpg
67
+ *.jpeg
68
+ *.png
69
+
70
+ # VidSmith logs (vidsmith.log and rotations)
71
+ *.log
72
+
73
+ # Local debug / scratch dumps (never committed)
74
+ out2/
75
+ rick.json
76
+ test_dump.json
77
+ yt_dlp_output.json
78
+ thumb_test_opts.json
79
+ ydl_init.txt
80
+ ytdlp_help.txt
81
+ scratch/
82
+ test_*/
83
+ thumb_test/
84
+ regression/
85
+ *.txt
@@ -0,0 +1,36 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ### Changed
6
+ - **Project renamed: MediaForge → VidSmith.** The previous name collided with an existing PyPI package. The distribution, import package (`vidsmith`), and terminal command (`vidsmith`) are all renamed; the on-screen logo and product name are rebranded. Functionality and behavior are unchanged.
7
+ - Settings are now stored under the `VidSmith` config directory. Existing settings from a previous MediaForge install are automatically copied over on first launch — no reconfiguration needed.
8
+ - Debug logs now write to `vidsmith.log` in the `VidSmith` config directory.
9
+ - Repository moved to [Nagamanikanta2331/VidSmith](https://github.com/Nagamanikanta2331/VidSmith); all project links updated.
10
+
11
+ ### Fixed
12
+ - Fixed an intermittent `UnicodeDecodeError` (`'charmap' codec can't decode byte …`) on Windows during post-download validation. Subprocess output from ffmpeg/ffprobe was being decoded with the legacy ANSI codepage (cp1252) instead of UTF-8, crashing the reader thread when video metadata contained non-ASCII characters (e.g. Hindi titles, fullwidth `|`, emoji). All captured-output subprocess calls now decode as UTF-8 with `errors="replace"`.
13
+
14
+ ## [1.0.0-rc1] - 2026-07-15
15
+
16
+ VidSmith has reached its first Release Candidate! This release finalizes the core architectural refactoring and prepares the project for broader real-world testing.
17
+
18
+ ### Added
19
+ - **Validation Pipeline**: Hardened the post-download validation architecture with an immutable `ValidationContext` and single-pass FFprobe inspection.
20
+ - **Windows Compatibility QA**: Introduced deterministic regression dataset generation via FFmpeg to systematically test Windows Explorer compatibility.
21
+ - **Documentation**: Added `WINDOWS_COMPATIBILITY.md`, `QA_CHECKLIST.md`, and `RELEASE_CHECKLIST.md` for standardized manual QA testing prior to releases.
22
+
23
+ ### Changed
24
+ - **Audio Output & Validation**: Decoupled thumbnail generation and metadata tagging to support dynamic, safe embedding for `MP3`, `M4A`, and `FLAC` with full graceful degradation when codecs are missing.
25
+ - **Cleanup Routine**: Strengthened cleanup workflows (`test_cleanup_e2e`) to ensure temporary files (`.part`, `.webp`, `.vtt`) are accurately purged without jeopardizing the final embedded payload.
26
+ - **Subtitle and Transcript Pipelines**: Standardized subtitle download logic to perfectly integrate into the main yt-dlp job structure, guaranteeing consistent retry handling and format fallback.
27
+ - **Transcript UX**: Improved the transcript extraction workflow to gracefully notify the user and restart the wizard if a selected language is unavailable, preventing abrupt exits.
28
+ - **Documentation**: Updated `README.md` with explicit, platform-specific installation instructions for FFmpeg and Node.js/Deno, and clarified that `yt-dlp` is automatically installed.
29
+
30
+ ### Fixed
31
+ - Fixed issues where ffmpeg crashes would improperly halt the entire validation pipeline instead of degrading gracefully.
32
+ - Removed duplicate artifacts and simplified execution paths across `YouTubeProvider`.
33
+ - Suppressed duplicate metadata injection processes.
34
+ - Fixed a critical `TypeError` string/int comparison bug in Best Download and Custom Video formats filtering.
35
+
36
+ VidSmith is now feature-complete for its 1.0.0 milestone. Future updates in the RC phase will focus solely on packaging, bug fixes, and optimization.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Naga Manikanta Nandyala
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,327 @@
1
+ Metadata-Version: 2.4
2
+ Name: vidsmith
3
+ Version: 1.0.0rc1
4
+ Summary: A production-grade, zero-config YouTube media downloader for your terminal.
5
+ Project-URL: Homepage, https://github.com/Nagamanikanta2331/VidSmith
6
+ Project-URL: Repository, https://github.com/Nagamanikanta2331/VidSmith
7
+ Project-URL: Issues, https://github.com/Nagamanikanta2331/VidSmith/issues
8
+ Project-URL: Changelog, https://github.com/Nagamanikanta2331/VidSmith/blob/main/CHANGELOG.md
9
+ Author-email: Naga Manikanta Nandyala <nagamanikantanandyala@outlook.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: audio,cli,download,ffmpeg,subtitles,video,youtube,yt-dlp
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Multimedia :: Sound/Audio
22
+ Classifier: Topic :: Multimedia :: Video
23
+ Classifier: Topic :: Utilities
24
+ Requires-Python: >=3.12
25
+ Requires-Dist: curl-cffi>=0.7.0
26
+ Requires-Dist: imageio-ffmpeg>=0.6.0
27
+ Requires-Dist: mutagen>=1.47.0
28
+ Requires-Dist: rich>=13.7.0
29
+ Requires-Dist: webvtt-py>=0.4.6
30
+ Requires-Dist: yt-dlp>=2024.1.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: black>=24.0; extra == 'dev'
33
+ Requires-Dist: build>=1.2; extra == 'dev'
34
+ Requires-Dist: mypy>=1.10; extra == 'dev'
35
+ Requires-Dist: pre-commit>=3.7; extra == 'dev'
36
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
37
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
38
+ Requires-Dist: pytest>=8.0; extra == 'dev'
39
+ Requires-Dist: ruff>=0.5.0; extra == 'dev'
40
+ Requires-Dist: twine>=5.0; extra == 'dev'
41
+ Provides-Extra: tui
42
+ Requires-Dist: textual>=0.61.0; extra == 'tui'
43
+ Requires-Dist: typer>=0.12.0; extra == 'tui'
44
+ Description-Content-Type: text/markdown
45
+
46
+ # VidSmith
47
+
48
+ > **🤖 Built by AI — Idea by the Owner**
49
+ > This entire project — all source code, tests, UI, and documentation — was developed by an AI coding assistant (Claude). The original idea, product direction, and ownership belong to the repository owner, [Naga Manikanta Nandyala](https://github.com/Nagamanikanta2331).
50
+
51
+ **A production-grade, zero-config YouTube media downloader for your terminal.**
52
+
53
+ VidSmith wraps the full power of [yt-dlp](https://github.com/yt-dlp/yt-dlp)
54
+ in a polished interactive CLI: paste a URL, press **1**, and get the best
55
+ possible file — same stream selection as the official yt-dlp CLI, with
56
+ subtitles, chapters, metadata, and cover art embedded automatically.
57
+
58
+ ```text
59
+ __ ___ _ ____ _ _ _
60
+ \ \ / (_) __| / ___| _ __ ___ (_) |_| |__
61
+ \ \ / /| |/ _` \___ \| '_ ` _ \| | __| '_ \
62
+ \ V / | | (_| |___) | | | | | | | |_| | | |
63
+ \_/ |_|\__,_|____/|_| |_| |_|_|\__|_| |_|
64
+ ```
65
+
66
+ [![CI](https://github.com/Nagamanikanta2331/VidSmith/actions/workflows/ci.yml/badge.svg)](https://github.com/Nagamanikanta2331/VidSmith/actions/workflows/ci.yml)
67
+ [![PyPI](https://img.shields.io/pypi/v/vidsmith)](https://pypi.org/project/vidsmith/)
68
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue)](https://python.org)
69
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
70
+
71
+ ---
72
+
73
+ ## Features
74
+
75
+ - ⭐ **Best Download** — one keypress, zero configuration. Selects the exact
76
+ VP9+Opus streams (`313+251/308+251/303+251/302+251`) and merges to MKV
77
+ without transcoding.
78
+ - 🎯 **Custom wizards** — quality, container (MP4/MKV/WebM), subtitles, audio
79
+ format, playlists — all through guided multi-step prompts.
80
+ - 🎵 **Audio mode** — MP3, M4A, FLAC, Opus, WAV with metadata and cover art.
81
+ - 📝 **Transcripts** — download captions and convert to TXT, Markdown, or JSON.
82
+ - 💬 **Professional subtitle handling** — many languages at once; failures
83
+ (e.g. HTTP 429) are reported per-language, never fatal.
84
+ - 🖼️ **Honest thumbnail embedding** — tells you exactly what each container
85
+ supports instead of failing silently.
86
+ - 📊 **Rich progress + summary** — live speed/ETA, then a full report:
87
+ resolution, FPS, HDR, codecs, bitrates, file size, subtitle outcome.
88
+ - 🩺 **`vidsmith doctor`** — one command to diagnose your environment.
89
+ - ⏯️ **Resume support** — interrupted downloads continue from `.part` files.
90
+
91
+ ### Screenshot
92
+
93
+ ```text
94
+ ╭──────────────────── ✅ Best Download Complete ────────────────────╮
95
+ │ │
96
+ │ Video Name Survive 30 Days Chained To A Stranger… │
97
+ │ Channel MrBeast │
98
+ │ Container MKV │
99
+ │ Resolution 1920x1080 FPS 30 fps │
100
+ │ Video Codec vp9 Video Bitrate 1490 kbps │
101
+ │ Audio Codec opus Audio Bitrate 128 kbps │
102
+ │ File Size 406.2 MB Download Time 2m 43s │
103
+ │ │
104
+ │ ✓ Metadata Embedded │
105
+ │ ✓ Thumbnail Embedded │
106
+ │ Supported by MKV container │
107
+ │ ✓ Resume Supported │
108
+ │ │
109
+ │ Primary Subtitle English │
110
+ │ Other Subtitles 23 languages │
111
+ │ Subtitles Downloaded 24 │
112
+ ╰───────────────────────────────────────────────────────────────────╯
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Installation
118
+
119
+ Install directly from GitHub (recommended until the first PyPI release):
120
+
121
+ ```bash
122
+ pip install git+https://github.com/Nagamanikanta2331/VidSmith.git
123
+ ```
124
+
125
+ Or clone and install from source:
126
+
127
+ ```bash
128
+ git clone https://github.com/Nagamanikanta2331/VidSmith.git
129
+ cd VidSmith
130
+ pip install -e .
131
+ ```
132
+
133
+ > **Note**: `pip install vidsmith` will work once the first release is published
134
+ > to PyPI. Until then, use one of the commands above.
135
+
136
+ ### Prerequisites
137
+ - **Python 3.12+**
138
+ - **yt-dlp**: Installed automatically for you when you run the installation command above. No manual installation is required!
139
+
140
+ ### Recommended System Tools
141
+ While VidSmith comes with fallbacks, installing these system tools ensures maximum performance and compatibility:
142
+
143
+ **1. FFmpeg (for media conversion and muxing)**
144
+ If not found, VidSmith uses a bundled fallback (`imageio-ffmpeg`), but a native installation is faster and more robust.
145
+ - **Windows:** `winget install ffmpeg` (or download from [gyan.dev](https://www.gyan.dev/ffmpeg/builds/))
146
+ - **macOS:** `brew install ffmpeg`
147
+ - **Linux:** `sudo apt install ffmpeg` (Ubuntu/Debian)
148
+
149
+ **2. Node.js or Deno (for complex YouTube extractions)**
150
+ YouTube occasionally requires executing JavaScript to extract certain video formats.
151
+ - **Windows/macOS/Linux:** Download from [Node.js](https://nodejs.org/) or install Deno via `iwr https://deno.land/install.ps1 -useb | iex` (Windows) / `curl -fsSL https://deno.land/install.sh | sh` (macOS/Linux).
152
+
153
+ Verify your environment:
154
+
155
+ ```bash
156
+ vidsmith doctor
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Quick Start
162
+
163
+ ```bash
164
+ vidsmith
165
+ ```
166
+
167
+ 1. Paste a YouTube URL (video, Shorts, or playlist) and press **Enter**.
168
+ 2. VidSmith analyses it and shows a menu — option **1** is always
169
+ **⭐ Best Download**.
170
+ 3. Press **1** + Enter. Done.
171
+
172
+ A live progress bar tracks the download; a summary panel reports exactly what
173
+ you got.
174
+
175
+ ---
176
+
177
+ ## Commands
178
+
179
+ | Command | Purpose |
180
+ |---------|---------|
181
+ | `vidsmith` | Launch the interactive app |
182
+ | `vidsmith doctor` | Diagnose environment (tools, network, YouTube access) |
183
+ | `vidsmith doctor --no-network` | Same, skipping connectivity checks |
184
+ | `vidsmith --version` | Print the version |
185
+
186
+ ---
187
+
188
+ ## Modes
189
+
190
+ ### ⭐ Recommended (Best Download)
191
+
192
+ Zero configuration. Automatically:
193
+
194
+ | What | How |
195
+ |------|-----|
196
+ | Video | VP9 preference chain: `313+251/308+251/303+251/302+251`, then `bestvideo+bestaudio` |
197
+ | Audio | Best available track (e.g. Opus 128k) |
198
+ | Container | MKV — holds any codec, subtitles, chapters, and cover art |
199
+ | Subtitles | Manual + auto captions downloaded and embedded |
200
+ | Metadata | Title, channel, date, description embedded |
201
+ | Chapters | Embedded when the video has them |
202
+ | Thumbnail | Embedded as MKV attachment (always visible) |
203
+
204
+ ### Custom video
205
+
206
+ Guided wizard: output directory → quality (Best/4K/2K/1080p/720p/480p/360p) →
207
+ container (MP4/MKV/WebM) → subtitles → confirm.
208
+
209
+ > Choosing MP4 restricts streams to MP4-compatible codecs for maximum device
210
+ > compatibility. Choose MKV for maximum quality.
211
+
212
+ ### Audio
213
+
214
+ Wizard: format (MP3/M4A/FLAC/Opus/WAV) → bitrate → thumbnail → metadata.
215
+
216
+ ### Transcript
217
+
218
+ Downloads captions and converts to clean TXT, Markdown, or JSON — with optional
219
+ timestamps.
220
+
221
+ ### Subtitles / Thumbnail only
222
+
223
+ Direct menu actions save subtitle files or the best thumbnail without
224
+ downloading media.
225
+
226
+ ---
227
+
228
+ ## Configuration
229
+
230
+ VidSmith is deliberately zero-config for the common case. Power users can
231
+ tune the provider via the `YouTubeProvider(config=...)` API:
232
+
233
+ | Key | Default | Purpose |
234
+ |-----|---------|---------|
235
+ | `download_retries` | `3` | Full-download retry attempts |
236
+ | `subtitle_sleep_interval` | `1` | Seconds between subtitle requests (429 protection) |
237
+ | `ffmpeg_location` | auto | Explicit FFmpeg path |
238
+ | `metadata_cache_size` | `16` | Analyzed-URL cache entries |
239
+
240
+ Persistent user settings (config file) are on the roadmap.
241
+
242
+ ---
243
+
244
+ ## Dependencies
245
+
246
+ | Package | Role |
247
+ |---------|------|
248
+ | `yt-dlp` | Extraction and downloading |
249
+ | `rich` | Terminal UI |
250
+ | `curl_cffi` | Browser impersonation (reduces YouTube rate limiting) |
251
+ | `mutagen` | Visible MP4/M4A cover-art atoms |
252
+ | `webvtt-py` | Transcript parsing |
253
+ | `imageio-ffmpeg` | Bundled FFmpeg fallback |
254
+
255
+ Optional (auto-detected, recommended):
256
+
257
+ - **Deno** or **Node.js** — JS runtime for full YouTube format parity
258
+ - **AtomicParsley** — alternative MP4 cover-art writer
259
+
260
+ ---
261
+
262
+ ## Troubleshooting
263
+
264
+ **Run `vidsmith doctor` first.** It diagnoses nearly every common problem.
265
+
266
+ | Symptom | Cause & fix |
267
+ |---------|-------------|
268
+ | "Impersonation … not available" | `pip install curl_cffi` |
269
+ | Thumbnail invisible in Windows Explorer (MP4/M4A) | `pip install mutagen` — or use MKV. Windows Explorer ignores ffmpeg's `attached_pic`; VLC/MediaInfo show it. |
270
+ | HTTP 429 on subtitles | YouTube rate limiting. VidSmith throttles and continues; failed languages are listed in the summary. Retry later for missing ones. |
271
+ | "Some formats may be missing" | Install [Deno](https://deno.com) (or Node.js). |
272
+ | Download smaller than other tools | Modern codecs such as VP9 give the same quality in half the size of H.264. Compare resolution/codec, not bytes. |
273
+ | Interrupted download | Rerun the same download — it resumes from `.part`. |
274
+
275
+ ## FAQ
276
+
277
+ **Why MKV by default?**
278
+ It's the only mainstream container that holds any codec plus subtitles,
279
+ chapters, and cover art without re-encoding — and it's what
280
+ `yt-dlp --merge-output-format mkv` produces. Choose MP4 in the custom wizard if
281
+ a device requires it.
282
+
283
+ **Is quality identical to yt-dlp?**
284
+ Best Download intentionally prefers VP9+Opus before falling back to yt-dlp's
285
+ generic bestvideo+bestaudio selector. Custom MKV downloads still use the normal
286
+ yt-dlp-style best selector.
287
+
288
+ **Does it re-encode?**
289
+ No. Streams are merged, never transcoded (except explicit audio-format
290
+ conversion in Audio mode).
291
+
292
+ **Playlists?**
293
+ Yes — Best Download and the custom wizard both support playlists with
294
+ per-item progress and failure reporting.
295
+
296
+ ---
297
+
298
+ ## Roadmap
299
+
300
+ - Persistent settings file (`~/.config/vidsmith/`)
301
+ - Subtitle/thumbnail embedding options in the custom wizard
302
+ - Non-interactive one-shot mode (`vidsmith <url> --best`)
303
+ - Textual full-screen TUI
304
+ - Additional providers behind the existing `Provider` ABC
305
+
306
+ ---
307
+
308
+ ## Contributing
309
+
310
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for setup,
311
+ quality gates, and PR guidelines. Please note the
312
+ [Code of Conduct](CODE_OF_CONDUCT.md).
313
+
314
+ ```bash
315
+ pip install -e ".[dev]"
316
+ pre-commit install
317
+ pytest
318
+ ```
319
+
320
+ ## License
321
+
322
+ [MIT](LICENSE) © Naga Manikanta Nandyala
323
+
324
+ ---
325
+
326
+ *VidSmith is an independent project built on yt-dlp. Download only content
327
+ you are authorized to access.*