Merge pull request #163 from arabcoders/dev
Fix and document presets.json
This commit is contained in:
commit
2e99ff1f5e
4 changed files with 109 additions and 51 deletions
34
README.md
34
README.md
|
|
@ -301,6 +301,40 @@ The `config/webhooks.json`, is a json file, which can be used to add webhook end
|
|||
]
|
||||
```
|
||||
|
||||
### presets.json File
|
||||
|
||||
The `config/preset.json`, is a json file, which can be used to add custom presets for selection in WebUI.
|
||||
|
||||
The file is supposed to be an array of objects, each object represent a preset, the schema for the object is as the following.
|
||||
```json5
|
||||
[
|
||||
{
|
||||
// (name: string) - REQUIRED - The preset name.
|
||||
"name": "My super preset",
|
||||
// (format: string) - REQUIRED - The required yt-dlp format. i.e. -f option in yt-dlp cli.
|
||||
"format": "best",
|
||||
// (postprocessors: array) - OPTIONAL - The postprocessors to run on the file. if it's preset or set to empty array, it will override the default postprocessors.
|
||||
"postprocessors": [
|
||||
// for example to embed thumbnail.
|
||||
{
|
||||
"key": "EmbedThumbnail",
|
||||
"already_have_thumbnail": false
|
||||
}
|
||||
],
|
||||
// (args: dict) - OPTIONAL - Extra yt-dlp arguments to pass to yt-dlp.
|
||||
"args": {
|
||||
// (key: string) - REQUIRED - The yt-dlp argument key.
|
||||
"writethumbnail": true
|
||||
}
|
||||
},
|
||||
{
|
||||
// another preset, etc...
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
For more expanded example please take look at the default presets file found in [app/library/presets.json](app/library/presets.json).
|
||||
|
||||
## Authentication
|
||||
|
||||
To enable basic authentication, set the `YTP_AUTH_USERNAME` and `YTP_AUTH_PASSWORD` environment variables. And restart the container.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
|
@ -69,49 +70,7 @@ class Config:
|
|||
started: int = 0
|
||||
ignore_ui: bool = False
|
||||
presets: list = [
|
||||
{"name": "default", "format": "default", "postprocessors": [], "args": {}},
|
||||
{
|
||||
"name": "Best video and audio",
|
||||
"format": "bv+ba/b",
|
||||
"args": {},
|
||||
},
|
||||
{
|
||||
"name": "1080p H264/m4a or best available",
|
||||
"format": "bv[height<=1080][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]",
|
||||
"args": {
|
||||
"format_sort": ["vcodec:h264"],
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "720p h264/m4a or best available",
|
||||
"format": "bv[height<=720][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]",
|
||||
"args": {
|
||||
"format_sort": ["vcodec:h264"],
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Audio only",
|
||||
"format": "bestaudio/best",
|
||||
"postprocessors": [
|
||||
{
|
||||
"key": "FFmpegExtractAudio",
|
||||
"preferredcodec": "best",
|
||||
"preferredquality": "5",
|
||||
"nopostoverwrites": False,
|
||||
},
|
||||
{"key": "FFmpegMetadata", "add_chapters": True, "add_metadata": True, "add_infojson": "if_exists"},
|
||||
{"key": "EmbedThumbnail", "already_have_thumbnail": False},
|
||||
{"key": "FFmpegConcat", "only_multi_video": True, "when": "playlist"},
|
||||
],
|
||||
"args": {
|
||||
"outtmpl": {"pl_thumbnail": ""},
|
||||
"ignoreerrors": "only_download",
|
||||
"retries": 10,
|
||||
"fragment_retries": 10,
|
||||
"writethumbnail": True,
|
||||
"extract_flat": "discard_in_playlist",
|
||||
},
|
||||
},
|
||||
{"name": "default", "format": "default"},
|
||||
]
|
||||
|
||||
_manual_vars: tuple = (
|
||||
|
|
@ -276,15 +235,24 @@ class Config:
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
# Load default presets.
|
||||
with open(os.path.join(os.path.dirname(__file__), "presets.json"), "r") as f:
|
||||
self.presets.extend(json.load(f))
|
||||
|
||||
# Load user defined presets.
|
||||
presetsFile = os.path.join(self.config_path, "presets.json")
|
||||
if os.path.exists(presetsFile) and os.path.getsize(presetsFile) > 0:
|
||||
LOG.info(f"Loading extra presets from '{presetsFile}'.")
|
||||
LOG.info(f"Loading user presets from '{presetsFile}'.")
|
||||
try:
|
||||
(presets, status, error) = load_file(presetsFile, list)
|
||||
if not status:
|
||||
LOG.error(f"Could not load presets file from '{presetsFile}'. '{error}'.")
|
||||
sys.exit(1)
|
||||
|
||||
if not isinstance(presets, list):
|
||||
LOG.error(f"Invalid presets file '{presetsFile}'. It's expected to be a list of objects.")
|
||||
sys.exit(1)
|
||||
|
||||
for preset in presets:
|
||||
if "name" not in preset:
|
||||
LOG.error(f"Missing 'name' key in preset '{preset}'.")
|
||||
|
|
@ -294,11 +262,13 @@ class Config:
|
|||
LOG.error(f"Missing 'format' key in preset '{preset}'.")
|
||||
continue
|
||||
|
||||
if "args" not in preset:
|
||||
preset["args"] = {}
|
||||
if "args" in preset and not isinstance(preset["args"], dict):
|
||||
LOG.error(f"Invalid 'args' key in preset '{preset}' it's expected to be dict.")
|
||||
continue
|
||||
|
||||
if "postprocessors" not in preset:
|
||||
preset["postprocessors"] = []
|
||||
if "postprocessors" in preset and not isinstance(preset["postprocessors"], list):
|
||||
LOG.error(f"Invalid 'postprocessors' key in preset '{preset}' it's expected to be list.")
|
||||
continue
|
||||
|
||||
self.presets.append(preset)
|
||||
except Exception:
|
||||
|
|
|
|||
54
app/library/presets.json
Normal file
54
app/library/presets.json
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
[
|
||||
{
|
||||
"name": "Best video and audio",
|
||||
"format": "bv+ba/b"
|
||||
},
|
||||
{
|
||||
"name": "1080p H264/m4a or best available",
|
||||
"format": "bv[height<=1080][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]",
|
||||
"args": {
|
||||
"format_sort": [
|
||||
"vcodec:h264"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "720p h264/m4a or best available",
|
||||
"format": "bv[height<=720][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]",
|
||||
"args": {
|
||||
"format_sort": [
|
||||
"vcodec:h264"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Audio only",
|
||||
"format": "bestaudio/best",
|
||||
"args": {
|
||||
"writethumbnail": true
|
||||
},
|
||||
"postprocessors": [
|
||||
{
|
||||
"key": "FFmpegExtractAudio",
|
||||
"preferredcodec": "best",
|
||||
"preferredquality": "5",
|
||||
"nopostoverwrites": false
|
||||
},
|
||||
{
|
||||
"key": "FFmpegMetadata",
|
||||
"add_chapters": true,
|
||||
"add_metadata": true,
|
||||
"add_infojson": "if_exists"
|
||||
},
|
||||
{
|
||||
"key": "EmbedThumbnail",
|
||||
"already_have_thumbnail": false
|
||||
},
|
||||
{
|
||||
"key": "FFmpegConcat",
|
||||
"only_multi_video": true,
|
||||
"when": "playlist"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -60,14 +60,14 @@
|
|||
<div class="field">
|
||||
<label class="label is-inline" for="output_format"
|
||||
v-tooltip="'Default Format: ' + config.app.output_template">
|
||||
Output Format
|
||||
Output Template
|
||||
</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" v-model="output_template" id="output_format"
|
||||
placeholder="Uses default output format naming if empty.">
|
||||
placeholder="Uses default output template naming if empty.">
|
||||
</div>
|
||||
<span class="subtitle is-6">
|
||||
All output format naming options can be found at <NuxtLink target="_blank" class="has-text-danger"
|
||||
All output template naming options can be found at <NuxtLink target="_blank" class="has-text-danger"
|
||||
href="https://github.com/yt-dlp/yt-dlp#output-template">this page</NuxtLink>.
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue