jellyfetch 0.1.1__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.
- jellyfetch-0.1.1/LICENSE +42 -0
- jellyfetch-0.1.1/PKG-INFO +76 -0
- jellyfetch-0.1.1/README.md +64 -0
- jellyfetch-0.1.1/jellyfetch/__init__.py +0 -0
- jellyfetch-0.1.1/jellyfetch/fetcher.py +89 -0
- jellyfetch-0.1.1/jellyfetch.egg-info/PKG-INFO +76 -0
- jellyfetch-0.1.1/jellyfetch.egg-info/SOURCES.txt +11 -0
- jellyfetch-0.1.1/jellyfetch.egg-info/dependency_links.txt +1 -0
- jellyfetch-0.1.1/jellyfetch.egg-info/entry_points.txt +2 -0
- jellyfetch-0.1.1/jellyfetch.egg-info/requires.txt +4 -0
- jellyfetch-0.1.1/jellyfetch.egg-info/top_level.txt +1 -0
- jellyfetch-0.1.1/pyproject.toml +12 -0
- jellyfetch-0.1.1/setup.cfg +4 -0
jellyfetch-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
|
2
|
+
|
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
4
|
+
distribute this software, either in source code form or as a compiled
|
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
6
|
+
means.
|
|
7
|
+
|
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
9
|
+
of this software dedicate any and all copyright interest in the
|
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
|
11
|
+
of the public at large and to the detriment of our heirs and
|
|
12
|
+
successors. We intend this dedication to be an overt act of
|
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
14
|
+
software under copyright law.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
For more information, please refer to <https://unlicense.org>
|
|
25
|
+
|
|
26
|
+
----------------------------------------------------------------------
|
|
27
|
+
THIRD-PARTY LICENSES & DEPENDENCIES
|
|
28
|
+
----------------------------------------------------------------------
|
|
29
|
+
While the core JellyFetch wrapper is licensed under the Unlicense, this
|
|
30
|
+
project relies on heavily bundled third-party dependencies that carry
|
|
31
|
+
their own licensing terms:
|
|
32
|
+
|
|
33
|
+
1. yt-dlp: The core extraction engine is licensed under the Unlicense,
|
|
34
|
+
but contains components licensed under MIT and ISC[cite: 5].
|
|
35
|
+
2. FFmpeg: The media post-processing and merging toolkit is licensed
|
|
36
|
+
under the GPLv3+ depending on the build[cite: 5].
|
|
37
|
+
3. yt-dlp-ejs / Deno: JavaScript evaluation runtimes utilizing MIT
|
|
38
|
+
and ISC components[cite: 5].
|
|
39
|
+
|
|
40
|
+
Users redistributing compiled Docker images or binaries of JellyFetch
|
|
41
|
+
must ensure compliance with the inherited GPLv3+ and MIT terms of these
|
|
42
|
+
underlying dependencies.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jellyfetch
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A feature-rich command-line media downloader and web dashboard
|
|
5
|
+
Description-Content-Type: text/markdown
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Dist: yt-dlp
|
|
8
|
+
Requires-Dist: flask
|
|
9
|
+
Requires-Dist: python-dotenv
|
|
10
|
+
Requires-Dist: yt-dlp-ejs
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
### JellyFetch 0.1.0
|
|
14
|
+
A feature-rich command-line media downloader and web dashboard
|
|
15
|
+
`docker compose up -d` Copy Docker instructions
|
|
16
|
+
|
|
17
|
+
* [Description](#description)
|
|
18
|
+
* [Dependencies](#dependencies)
|
|
19
|
+
* [Installation](#installation)
|
|
20
|
+
* [Usage and Dashboard](#usage-and-dashboard)
|
|
21
|
+
* [Configuration](#configuration)
|
|
22
|
+
* [Extracted Metadata](#extracted-metadata)
|
|
23
|
+
* [Examples](#examples)
|
|
24
|
+
* [Maintenance and Cache](#maintenance-and-cache)
|
|
25
|
+
|
|
26
|
+
Official repository: https://github.com/fbellegarde/jellyfetch
|
|
27
|
+
|
|
28
|
+
JellyFetch is a feature-rich, full-stack media acquisition platform. Built as a custom wrapper around yt-dlp—a feature-rich command-line audio/video downloader with support for thousands of sites—it provides a highly robust terminal CLI alongside a premium, single-page web dashboard. It automatically routes downloaded media (Movies, TV, Music, Social Clips) into your host file system and triggers library syncs across Jellyfin and Navidrome.
|
|
29
|
+
|
|
30
|
+
**Important**: Any user experiencing an issue with downloads or signature extraction should flush the system cache via the Web UI before submitting a bug report.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
### DEPENDENCIES
|
|
35
|
+
Python versions 3.10+ (CPython) are supported. While some dependencies are optional for basic yt-dlp usage, the following are heavily utilized by the JellyFetch Docker container:
|
|
36
|
+
|
|
37
|
+
#### Strongly recommended
|
|
38
|
+
* **ffmpeg and ffprobe** - Required for merging separate video and audio files, as well as for various post-processing tasks.
|
|
39
|
+
* **yt-dlp-ejs** - Required for full YouTube support. Licensed under Unlicense, bundles MIT and ISC components.
|
|
40
|
+
* **deno** - A JavaScript runtime/engine recommended to run yt-dlp-ejs.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### INSTALLATION
|
|
45
|
+
|
|
46
|
+
**Docker Deployment (Recommended)**
|
|
47
|
+
JellyFetch is designed to run in an isolated container while securely mounting your host media drives.
|
|
48
|
+
```bash
|
|
49
|
+
git clone [https://github.com/fbellegarde/jellyfetch.git](https://github.com/fbellegarde/jellyfetch.git) && cd jellyfetch
|
|
50
|
+
cp web/.env.example web/.env
|
|
51
|
+
docker compose up --build -d
|
|
52
|
+
Local Development (WSL/Linux)Bashsource venv/bin/activate
|
|
53
|
+
pip install -e .
|
|
54
|
+
python web/server.py
|
|
55
|
+
USAGE AND DASHBOARDWeb Interface OptionsThe JellyFetch web dashboard is accessible by default at http://127.0.0.1:5547 and operates as a fully dynamic Single Page Application (SPA).Universal Drag-and-Drop: Drag any URL from your browser directly onto the UI window to instantly trigger the Metadata Inspector.Metadata Inspector: Previews the thumbnail, uploader, exact duration, and description parsed from the internal extraction dictionary before downloading.Hardware Audio Visualizer: The media player features a real-time HTML5 Canvas waveform visualizer that reacts to streaming media frequencies.Play Queue & Multi-Select: Add media to your queue for automatic transitions, or use Shift+Click in Table View for bulk queueing and deletion.Picture-in-Picture (PiP): Float the video player on top of your OS desktop using the native browser PiP API.CLI OptionsJellyFetch exposes the download command globally to your terminal, allowing you to pass explicit formats.Plaintext-h, --help Print this help text and exit
|
|
56
|
+
auto (Default) Analyzes the URL and metadata to automatically
|
|
57
|
+
route files to the correct host directory.
|
|
58
|
+
mp3 Convert video files to audio-only files[cite: 5].
|
|
59
|
+
Forces 192kbps audio extraction.
|
|
60
|
+
mkv Remux the video into another container[cite: 5].
|
|
61
|
+
Forces merging the best video and audio into an MKV container.
|
|
62
|
+
all Archives all available formats.
|
|
63
|
+
CONFIGURATIONConfigure JellyFetch by modifying the .env file in the /web directory. If you alter your configuration or core files, run docker compose up --build -d to rebuild the container.VariableCategoryDefault ValueDescriptionHOSTServer0.0.0.0The binding address.PORTServer5547The port the Flask API and Web UI run on.FLASK_DEBUGServerFalseSet to True for hot-reloading during development.APP_NAMEBrandingJellyFetchAlters the text in the top-left sidebar.THEME_PRIMARYBranding#a855f7Hex code for the primary accent color.MAX_GRID_ITEMSBranding500Limits the maximum files parsed per directory to prevent DOM lag.PATH_MOVIESMounts/mnt/e/.../MoviesThe internal path where your host movie drive is mounted.PATH_TVMounts/mnt/e/.../TV ShowsThe internal path where your host TV drive is mounted.PATH_MUSICMounts/mnt/e/.../MusicThe internal path where your host music drive is mounted.PATH_SOCIALMounts/mnt/e/.../ClipsThe internal path where your host social clips drive is mounted.JELLYFIN_URLIntegrationshttp://...Your local Jellyfin instance address.JELLYFIN_API_KEYIntegrationsNoneGenerate this in Jellyfin to sync via the Web UI.NAVIDROME_URLIntegrationshttp://...Your local Navidrome instance address.EXTRACTED METADATAJellyFetch extracts metadata and saves it as .info.json files. The UI parses these files to display detailed information. The following fields are actively extracted and utilized:is_live (boolean): Whether this video is a live stream or a fixed-length video[cite: 5].duration (numeric): Length of the video[cite: 5].extractor (string): Name of the extractor[cite: 5].playlist_id (string): Identifier of the playlist that contains the video[cite: 5].playlist_title (string): Name of the playlist that contains the video[cite: 5].playlist_count (numeric): Total number of items in the playlist. May not be known if entire playlist is not extracted[cite: 5].EXAMPLESBash# Boot the isolated JellyFetch container in detached mode
|
|
64
|
+
$ docker compose up --build -d
|
|
65
|
+
|
|
66
|
+
# Download and route a standard video via CLI
|
|
67
|
+
$ download [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
68
|
+
|
|
69
|
+
# Download the best format that contains video,
|
|
70
|
+
# and if it doesn't already have an audio stream, merge it with best audio-only format[cite: 5].
|
|
71
|
+
$ download mkv [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
72
|
+
|
|
73
|
+
# Download best video available via direct link over HTTP/HTTPS protocol,
|
|
74
|
+
# or the best video available via any protocol if there is no such video[cite: 5].
|
|
75
|
+
$ download auto [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
76
|
+
MAINTENANCE AND CACHERebuilding: If you modify server.py, index.html, or alter your .env configuration, you must rebuild the Docker container (docker compose up --build -d) to apply the changes.System Cache: To maintain optimal extraction speeds and bypass stale signatures, yt-dlp utilizes a local cache. If downloads fail due to signature errors, navigate to the System Settings tab in the Web UI and click Flush Cache to instantly clear the internal cache safely without restarting the container.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
### JellyFetch 0.1.0
|
|
2
|
+
A feature-rich command-line media downloader and web dashboard
|
|
3
|
+
`docker compose up -d` Copy Docker instructions
|
|
4
|
+
|
|
5
|
+
* [Description](#description)
|
|
6
|
+
* [Dependencies](#dependencies)
|
|
7
|
+
* [Installation](#installation)
|
|
8
|
+
* [Usage and Dashboard](#usage-and-dashboard)
|
|
9
|
+
* [Configuration](#configuration)
|
|
10
|
+
* [Extracted Metadata](#extracted-metadata)
|
|
11
|
+
* [Examples](#examples)
|
|
12
|
+
* [Maintenance and Cache](#maintenance-and-cache)
|
|
13
|
+
|
|
14
|
+
Official repository: https://github.com/fbellegarde/jellyfetch
|
|
15
|
+
|
|
16
|
+
JellyFetch is a feature-rich, full-stack media acquisition platform. Built as a custom wrapper around yt-dlp—a feature-rich command-line audio/video downloader with support for thousands of sites—it provides a highly robust terminal CLI alongside a premium, single-page web dashboard. It automatically routes downloaded media (Movies, TV, Music, Social Clips) into your host file system and triggers library syncs across Jellyfin and Navidrome.
|
|
17
|
+
|
|
18
|
+
**Important**: Any user experiencing an issue with downloads or signature extraction should flush the system cache via the Web UI before submitting a bug report.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
### DEPENDENCIES
|
|
23
|
+
Python versions 3.10+ (CPython) are supported. While some dependencies are optional for basic yt-dlp usage, the following are heavily utilized by the JellyFetch Docker container:
|
|
24
|
+
|
|
25
|
+
#### Strongly recommended
|
|
26
|
+
* **ffmpeg and ffprobe** - Required for merging separate video and audio files, as well as for various post-processing tasks.
|
|
27
|
+
* **yt-dlp-ejs** - Required for full YouTube support. Licensed under Unlicense, bundles MIT and ISC components.
|
|
28
|
+
* **deno** - A JavaScript runtime/engine recommended to run yt-dlp-ejs.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### INSTALLATION
|
|
33
|
+
|
|
34
|
+
**Docker Deployment (Recommended)**
|
|
35
|
+
JellyFetch is designed to run in an isolated container while securely mounting your host media drives.
|
|
36
|
+
```bash
|
|
37
|
+
git clone [https://github.com/fbellegarde/jellyfetch.git](https://github.com/fbellegarde/jellyfetch.git) && cd jellyfetch
|
|
38
|
+
cp web/.env.example web/.env
|
|
39
|
+
docker compose up --build -d
|
|
40
|
+
Local Development (WSL/Linux)Bashsource venv/bin/activate
|
|
41
|
+
pip install -e .
|
|
42
|
+
python web/server.py
|
|
43
|
+
USAGE AND DASHBOARDWeb Interface OptionsThe JellyFetch web dashboard is accessible by default at http://127.0.0.1:5547 and operates as a fully dynamic Single Page Application (SPA).Universal Drag-and-Drop: Drag any URL from your browser directly onto the UI window to instantly trigger the Metadata Inspector.Metadata Inspector: Previews the thumbnail, uploader, exact duration, and description parsed from the internal extraction dictionary before downloading.Hardware Audio Visualizer: The media player features a real-time HTML5 Canvas waveform visualizer that reacts to streaming media frequencies.Play Queue & Multi-Select: Add media to your queue for automatic transitions, or use Shift+Click in Table View for bulk queueing and deletion.Picture-in-Picture (PiP): Float the video player on top of your OS desktop using the native browser PiP API.CLI OptionsJellyFetch exposes the download command globally to your terminal, allowing you to pass explicit formats.Plaintext-h, --help Print this help text and exit
|
|
44
|
+
auto (Default) Analyzes the URL and metadata to automatically
|
|
45
|
+
route files to the correct host directory.
|
|
46
|
+
mp3 Convert video files to audio-only files[cite: 5].
|
|
47
|
+
Forces 192kbps audio extraction.
|
|
48
|
+
mkv Remux the video into another container[cite: 5].
|
|
49
|
+
Forces merging the best video and audio into an MKV container.
|
|
50
|
+
all Archives all available formats.
|
|
51
|
+
CONFIGURATIONConfigure JellyFetch by modifying the .env file in the /web directory. If you alter your configuration or core files, run docker compose up --build -d to rebuild the container.VariableCategoryDefault ValueDescriptionHOSTServer0.0.0.0The binding address.PORTServer5547The port the Flask API and Web UI run on.FLASK_DEBUGServerFalseSet to True for hot-reloading during development.APP_NAMEBrandingJellyFetchAlters the text in the top-left sidebar.THEME_PRIMARYBranding#a855f7Hex code for the primary accent color.MAX_GRID_ITEMSBranding500Limits the maximum files parsed per directory to prevent DOM lag.PATH_MOVIESMounts/mnt/e/.../MoviesThe internal path where your host movie drive is mounted.PATH_TVMounts/mnt/e/.../TV ShowsThe internal path where your host TV drive is mounted.PATH_MUSICMounts/mnt/e/.../MusicThe internal path where your host music drive is mounted.PATH_SOCIALMounts/mnt/e/.../ClipsThe internal path where your host social clips drive is mounted.JELLYFIN_URLIntegrationshttp://...Your local Jellyfin instance address.JELLYFIN_API_KEYIntegrationsNoneGenerate this in Jellyfin to sync via the Web UI.NAVIDROME_URLIntegrationshttp://...Your local Navidrome instance address.EXTRACTED METADATAJellyFetch extracts metadata and saves it as .info.json files. The UI parses these files to display detailed information. The following fields are actively extracted and utilized:is_live (boolean): Whether this video is a live stream or a fixed-length video[cite: 5].duration (numeric): Length of the video[cite: 5].extractor (string): Name of the extractor[cite: 5].playlist_id (string): Identifier of the playlist that contains the video[cite: 5].playlist_title (string): Name of the playlist that contains the video[cite: 5].playlist_count (numeric): Total number of items in the playlist. May not be known if entire playlist is not extracted[cite: 5].EXAMPLESBash# Boot the isolated JellyFetch container in detached mode
|
|
52
|
+
$ docker compose up --build -d
|
|
53
|
+
|
|
54
|
+
# Download and route a standard video via CLI
|
|
55
|
+
$ download [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
56
|
+
|
|
57
|
+
# Download the best format that contains video,
|
|
58
|
+
# and if it doesn't already have an audio stream, merge it with best audio-only format[cite: 5].
|
|
59
|
+
$ download mkv [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
60
|
+
|
|
61
|
+
# Download best video available via direct link over HTTP/HTTPS protocol,
|
|
62
|
+
# or the best video available via any protocol if there is no such video[cite: 5].
|
|
63
|
+
$ download auto [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
64
|
+
MAINTENANCE AND CACHERebuilding: If you modify server.py, index.html, or alter your .env configuration, you must rebuild the Docker container (docker compose up --build -d) to apply the changes.System Cache: To maintain optimal extraction speeds and bypass stale signatures, yt-dlp utilizes a local cache. If downloads fail due to signature errors, navigate to the System Settings tab in the Web UI and click Flush Cache to instantly clear the internal cache safely without restarting the container.
|
|
File without changes
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import argparse
|
|
3
|
+
from yt_dlp import YoutubeDL
|
|
4
|
+
|
|
5
|
+
def determine_save_path(url, info):
|
|
6
|
+
"""Dynamically routes downloads based on metadata and environment variables."""
|
|
7
|
+
movies_dir = os.getenv("PATH_MOVIES", "/mnt/e/Media/Jellyfin/Movies")
|
|
8
|
+
tv_dir = os.getenv("PATH_TV", "/mnt/e/Media/Jellyfin/TV Shows")
|
|
9
|
+
music_dir = os.getenv("PATH_MUSIC", "/mnt/e/Media/Music")
|
|
10
|
+
social_dir = os.getenv("PATH_SOCIAL", "/mnt/e/Media/Jellyfin/YouTubeClips")
|
|
11
|
+
|
|
12
|
+
url_lower = url.lower()
|
|
13
|
+
|
|
14
|
+
# 1. Music Routing
|
|
15
|
+
if "music.youtube.com" in url_lower or "soundcloud.com" in url_lower or info.get('artist'):
|
|
16
|
+
return music_dir
|
|
17
|
+
# 2. TV Series / Playlist Routing
|
|
18
|
+
if info.get('series') or info.get('playlist'):
|
|
19
|
+
return tv_dir
|
|
20
|
+
# 3. Social Media & Clips
|
|
21
|
+
if any(domain in url_lower for domain in ["tiktok.com", "twitter.com", "x.com", "instagram.com", "youtube.com", "youtu.be"]):
|
|
22
|
+
return social_dir
|
|
23
|
+
# 4. Movies Default Fallback
|
|
24
|
+
return movies_dir
|
|
25
|
+
|
|
26
|
+
def get_media(url, requested_format="auto"):
|
|
27
|
+
print(f"[JellyFetch] Inspecting metadata for {url}...")
|
|
28
|
+
with YoutubeDL({'quiet': True}) as ydl:
|
|
29
|
+
info = ydl.extract_info(url, download=False)
|
|
30
|
+
|
|
31
|
+
target_dir = determine_save_path(url, info)
|
|
32
|
+
print(f"[JellyFetch] Routing to: {target_dir}")
|
|
33
|
+
|
|
34
|
+
ydl_opts = {
|
|
35
|
+
'paths': {'home': target_dir},
|
|
36
|
+
'postprocessors': [{'key': 'FFmpegMetadata'}, {'key': 'EmbedThumbnail'}],
|
|
37
|
+
'writethumbnail': True,
|
|
38
|
+
'writeinfojson': True,
|
|
39
|
+
'clean_infojson': True,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if requested_format in ['mp3', 'flac', 'wav', 'm4a', 'opus', 'aac']:
|
|
43
|
+
ydl_opts['format'] = 'bestaudio/best'
|
|
44
|
+
ydl_opts['postprocessors'].insert(0, {'key': 'FFmpegExtractAudio', 'preferredcodec': requested_format})
|
|
45
|
+
if "Music" in target_dir or target_dir == os.getenv("PATH_MUSIC"):
|
|
46
|
+
ydl_opts['outtmpl'] = '%(artist|Unknown Artist)s/%(album|Unknown Album)s/%(title)s [%(id)s].%(ext)s'
|
|
47
|
+
else:
|
|
48
|
+
ydl_opts['outtmpl'] = '%(title)s [%(id)s].%(ext)s'
|
|
49
|
+
|
|
50
|
+
elif requested_format in ['mp4', 'mkv', 'webm', 'mov']:
|
|
51
|
+
ydl_opts['format'] = 'bestvideo+bestaudio/best'
|
|
52
|
+
ydl_opts['merge_output_format'] = requested_format
|
|
53
|
+
ydl_opts['outtmpl'] = '%(title)s [%(id)s].%(ext)s'
|
|
54
|
+
|
|
55
|
+
elif requested_format == "all":
|
|
56
|
+
ydl_opts['format'] = 'all'
|
|
57
|
+
ydl_opts['outtmpl'] = '%(title)s.f%(format_id)s.%(ext)s'
|
|
58
|
+
|
|
59
|
+
else:
|
|
60
|
+
if "Music" in target_dir or target_dir == os.getenv("PATH_MUSIC"):
|
|
61
|
+
ydl_opts['format'] = 'bestaudio/best'
|
|
62
|
+
ydl_opts['postprocessors'].insert(0, {'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192'})
|
|
63
|
+
ydl_opts['outtmpl'] = '%(artist|Unknown Artist)s/%(album|Unknown Album)s/%(title)s [%(id)s].%(ext)s'
|
|
64
|
+
else:
|
|
65
|
+
ydl_opts['format'] = 'bestvideo+bestaudio/best'
|
|
66
|
+
ydl_opts['outtmpl'] = '%(title)s [%(id)s].%(ext)s'
|
|
67
|
+
|
|
68
|
+
with YoutubeDL(ydl_opts) as ydl:
|
|
69
|
+
ydl.download([url])
|
|
70
|
+
|
|
71
|
+
def main():
|
|
72
|
+
parser = argparse.ArgumentParser(description="JellyFetch Media Downloader")
|
|
73
|
+
parser.add_argument("args", nargs="+", help="[format] URL or just URL")
|
|
74
|
+
args = parser.parse_args().args
|
|
75
|
+
|
|
76
|
+
if len(args) == 2:
|
|
77
|
+
req_fmt = args[0].lower()
|
|
78
|
+
url = args[1]
|
|
79
|
+
elif len(args) == 1:
|
|
80
|
+
req_fmt = "auto"
|
|
81
|
+
url = args[0]
|
|
82
|
+
else:
|
|
83
|
+
print("Usage: download [format] <url>")
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
get_media(url, req_fmt)
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
main()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jellyfetch
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A feature-rich command-line media downloader and web dashboard
|
|
5
|
+
Description-Content-Type: text/markdown
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Dist: yt-dlp
|
|
8
|
+
Requires-Dist: flask
|
|
9
|
+
Requires-Dist: python-dotenv
|
|
10
|
+
Requires-Dist: yt-dlp-ejs
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
### JellyFetch 0.1.0
|
|
14
|
+
A feature-rich command-line media downloader and web dashboard
|
|
15
|
+
`docker compose up -d` Copy Docker instructions
|
|
16
|
+
|
|
17
|
+
* [Description](#description)
|
|
18
|
+
* [Dependencies](#dependencies)
|
|
19
|
+
* [Installation](#installation)
|
|
20
|
+
* [Usage and Dashboard](#usage-and-dashboard)
|
|
21
|
+
* [Configuration](#configuration)
|
|
22
|
+
* [Extracted Metadata](#extracted-metadata)
|
|
23
|
+
* [Examples](#examples)
|
|
24
|
+
* [Maintenance and Cache](#maintenance-and-cache)
|
|
25
|
+
|
|
26
|
+
Official repository: https://github.com/fbellegarde/jellyfetch
|
|
27
|
+
|
|
28
|
+
JellyFetch is a feature-rich, full-stack media acquisition platform. Built as a custom wrapper around yt-dlp—a feature-rich command-line audio/video downloader with support for thousands of sites—it provides a highly robust terminal CLI alongside a premium, single-page web dashboard. It automatically routes downloaded media (Movies, TV, Music, Social Clips) into your host file system and triggers library syncs across Jellyfin and Navidrome.
|
|
29
|
+
|
|
30
|
+
**Important**: Any user experiencing an issue with downloads or signature extraction should flush the system cache via the Web UI before submitting a bug report.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
### DEPENDENCIES
|
|
35
|
+
Python versions 3.10+ (CPython) are supported. While some dependencies are optional for basic yt-dlp usage, the following are heavily utilized by the JellyFetch Docker container:
|
|
36
|
+
|
|
37
|
+
#### Strongly recommended
|
|
38
|
+
* **ffmpeg and ffprobe** - Required for merging separate video and audio files, as well as for various post-processing tasks.
|
|
39
|
+
* **yt-dlp-ejs** - Required for full YouTube support. Licensed under Unlicense, bundles MIT and ISC components.
|
|
40
|
+
* **deno** - A JavaScript runtime/engine recommended to run yt-dlp-ejs.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
### INSTALLATION
|
|
45
|
+
|
|
46
|
+
**Docker Deployment (Recommended)**
|
|
47
|
+
JellyFetch is designed to run in an isolated container while securely mounting your host media drives.
|
|
48
|
+
```bash
|
|
49
|
+
git clone [https://github.com/fbellegarde/jellyfetch.git](https://github.com/fbellegarde/jellyfetch.git) && cd jellyfetch
|
|
50
|
+
cp web/.env.example web/.env
|
|
51
|
+
docker compose up --build -d
|
|
52
|
+
Local Development (WSL/Linux)Bashsource venv/bin/activate
|
|
53
|
+
pip install -e .
|
|
54
|
+
python web/server.py
|
|
55
|
+
USAGE AND DASHBOARDWeb Interface OptionsThe JellyFetch web dashboard is accessible by default at http://127.0.0.1:5547 and operates as a fully dynamic Single Page Application (SPA).Universal Drag-and-Drop: Drag any URL from your browser directly onto the UI window to instantly trigger the Metadata Inspector.Metadata Inspector: Previews the thumbnail, uploader, exact duration, and description parsed from the internal extraction dictionary before downloading.Hardware Audio Visualizer: The media player features a real-time HTML5 Canvas waveform visualizer that reacts to streaming media frequencies.Play Queue & Multi-Select: Add media to your queue for automatic transitions, or use Shift+Click in Table View for bulk queueing and deletion.Picture-in-Picture (PiP): Float the video player on top of your OS desktop using the native browser PiP API.CLI OptionsJellyFetch exposes the download command globally to your terminal, allowing you to pass explicit formats.Plaintext-h, --help Print this help text and exit
|
|
56
|
+
auto (Default) Analyzes the URL and metadata to automatically
|
|
57
|
+
route files to the correct host directory.
|
|
58
|
+
mp3 Convert video files to audio-only files[cite: 5].
|
|
59
|
+
Forces 192kbps audio extraction.
|
|
60
|
+
mkv Remux the video into another container[cite: 5].
|
|
61
|
+
Forces merging the best video and audio into an MKV container.
|
|
62
|
+
all Archives all available formats.
|
|
63
|
+
CONFIGURATIONConfigure JellyFetch by modifying the .env file in the /web directory. If you alter your configuration or core files, run docker compose up --build -d to rebuild the container.VariableCategoryDefault ValueDescriptionHOSTServer0.0.0.0The binding address.PORTServer5547The port the Flask API and Web UI run on.FLASK_DEBUGServerFalseSet to True for hot-reloading during development.APP_NAMEBrandingJellyFetchAlters the text in the top-left sidebar.THEME_PRIMARYBranding#a855f7Hex code for the primary accent color.MAX_GRID_ITEMSBranding500Limits the maximum files parsed per directory to prevent DOM lag.PATH_MOVIESMounts/mnt/e/.../MoviesThe internal path where your host movie drive is mounted.PATH_TVMounts/mnt/e/.../TV ShowsThe internal path where your host TV drive is mounted.PATH_MUSICMounts/mnt/e/.../MusicThe internal path where your host music drive is mounted.PATH_SOCIALMounts/mnt/e/.../ClipsThe internal path where your host social clips drive is mounted.JELLYFIN_URLIntegrationshttp://...Your local Jellyfin instance address.JELLYFIN_API_KEYIntegrationsNoneGenerate this in Jellyfin to sync via the Web UI.NAVIDROME_URLIntegrationshttp://...Your local Navidrome instance address.EXTRACTED METADATAJellyFetch extracts metadata and saves it as .info.json files. The UI parses these files to display detailed information. The following fields are actively extracted and utilized:is_live (boolean): Whether this video is a live stream or a fixed-length video[cite: 5].duration (numeric): Length of the video[cite: 5].extractor (string): Name of the extractor[cite: 5].playlist_id (string): Identifier of the playlist that contains the video[cite: 5].playlist_title (string): Name of the playlist that contains the video[cite: 5].playlist_count (numeric): Total number of items in the playlist. May not be known if entire playlist is not extracted[cite: 5].EXAMPLESBash# Boot the isolated JellyFetch container in detached mode
|
|
64
|
+
$ docker compose up --build -d
|
|
65
|
+
|
|
66
|
+
# Download and route a standard video via CLI
|
|
67
|
+
$ download [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
68
|
+
|
|
69
|
+
# Download the best format that contains video,
|
|
70
|
+
# and if it doesn't already have an audio stream, merge it with best audio-only format[cite: 5].
|
|
71
|
+
$ download mkv [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
72
|
+
|
|
73
|
+
# Download best video available via direct link over HTTP/HTTPS protocol,
|
|
74
|
+
# or the best video available via any protocol if there is no such video[cite: 5].
|
|
75
|
+
$ download auto [https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=)...
|
|
76
|
+
MAINTENANCE AND CACHERebuilding: If you modify server.py, index.html, or alter your .env configuration, you must rebuild the Docker container (docker compose up --build -d) to apply the changes.System Cache: To maintain optimal extraction speeds and bypass stale signatures, yt-dlp utilizes a local cache. If downloads fail due to signature errors, navigate to the System Settings tab in the Web UI and click Flush Cache to instantly clear the internal cache safely without restarting the container.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
jellyfetch/__init__.py
|
|
5
|
+
jellyfetch/fetcher.py
|
|
6
|
+
jellyfetch.egg-info/PKG-INFO
|
|
7
|
+
jellyfetch.egg-info/SOURCES.txt
|
|
8
|
+
jellyfetch.egg-info/dependency_links.txt
|
|
9
|
+
jellyfetch.egg-info/entry_points.txt
|
|
10
|
+
jellyfetch.egg-info/requires.txt
|
|
11
|
+
jellyfetch.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
jellyfetch
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "jellyfetch"
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
description = "A feature-rich command-line media downloader and web dashboard"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
dependencies = ["yt-dlp", "flask", "python-dotenv", "yt-dlp-ejs"]
|
|
7
|
+
|
|
8
|
+
[project.scripts]
|
|
9
|
+
download = "jellyfetch.fetcher:main"
|
|
10
|
+
|
|
11
|
+
[tool.setuptools]
|
|
12
|
+
packages = ["jellyfetch"]
|