Files
CinemaTrailers4Jellyfins/Jellyfin.Plugin.CinemaTrailers4Jellyfins/Configuration/config.html
Martin c2d2b1ae44
Some checks failed
Publish Release / release (push) Failing after 17s
Initial commit: CinemaTrailers4Jellyfins plugin
Adapted from Trailers4Jellyfin: keeps TMDB/YouTube trailer downloading,
the scheduled task, language/source/date filters, and trailer rotation,
but drops cinema-mode/IIntroProvider entirely. Each trailer now ships in
its own fake-movie folder (placeholder video + locked NFO + trailer) for
use with a Cinema Mode / trailer pre-roll plugin.
2026-06-08 14:24:28 -04:00

303 lines
21 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>CinemaTrailers4Jellyfins</title>
</head>
<body>
<div data-role="page" class="page type-interior pluginConfigurationPage cinemaTrailers4JellyfinsConfigPage"
data-require="emby-input,emby-button,emby-checkbox,emby-select">
<div data-role="content">
<div class="content-primary">
<form class="cinemaTrailers4JellyfinsConfigPage">
<div class="sectionTitleContainer flex align-items-center">
<h2 class="sectionTitle">CinemaTrailers4Jellyfins</h2>
<a is="emby-linkbutton" class="raised button-alt headerHelpButton emby-button"
target="_blank" href="https://www.git.quarantinedstudio.com/mvezina/CinemaTrailers4Jellyfins#readme">Help</a>
</div>
<div class="verticalSection">
<p>
Downloads trailers for <strong>upcoming and recently released movies not in your library</strong>
from TMDB/YouTube and stores each one inside its own fake-movie folder, ready to be
picked up by a Cinema Mode / trailer pre-roll plugin.
</p>
<p style="margin-top:0">
A free TMDB API key is required.
<a href="https://www.themoviedb.org/settings/api" target="_blank" rel="noopener">Get one here →</a>
</p>
</div>
<!-- TMDB -->
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend><h3 class="sectionTitle">TMDB</h3></legend>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="tmdb-api-key">TMDB API Key</label>
<input type="password" id="tmdb-api-key" is="emby-input" autocomplete="off" />
<div class="fieldDescription">
Your TMDB Read Access Token (JWT) or v3 API key from
<a href="https://www.themoviedb.org/settings/api" target="_blank" rel="noopener">themoviedb.org/settings/api</a>.
</div>
</div>
</fieldset>
<!-- Languages -->
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend><h3 class="sectionTitle">Trailer Languages</h3></legend>
<p class="fieldDescription">
Only download trailers in the selected languages.
Leave everything unchecked to allow all languages.
</p>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0 2em;">
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-en" /><span>English</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-es" /><span>Spanish</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-fr" /><span>French</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-de" /><span>German</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-it" /><span>Italian</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-pt" /><span>Portuguese</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-nl" /><span>Dutch</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-ru" /><span>Russian</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-pl" /><span>Polish</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-sv" /><span>Swedish</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-no" /><span>Norwegian</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-da" /><span>Danish</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-ja" /><span>Japanese</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-ko" /><span>Korean</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-zh" /><span>Chinese</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-ar" /><span>Arabic</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-hi" /><span>Hindi</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-tr" /><span>Turkish</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-th" /><span>Thai</span></label></div>
<div class="checkboxContainer"><label><input is="emby-checkbox" type="checkbox" id="lang-id" /><span>Indonesian</span></label></div>
</div>
</fieldset>
<!-- Sources -->
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend><h3 class="sectionTitle">Trailer Sources</h3></legend>
<p class="fieldDescription">
Choose which TMDB lists to pull trailers from. Enable multiple for more variety.
</p>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="source-now-playing" />
<span>Now Playing</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Movies currently in theatres. Refreshes weekly on TMDB.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="source-upcoming" />
<span>Upcoming</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Movies coming soon to theatres. Great for seeing what's on the horizon.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="source-popular" />
<span>Popular</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Most popular movies on TMDB right now, filtered by the date range below.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="source-top-rated" />
<span>Top Rated</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Highest rated movies on TMDB, filtered by the date range below.
</div>
</div>
</fieldset>
<!-- Date Range -->
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend><h3 class="sectionTitle">Date Range</h3></legend>
<div class="selectContainer">
<label class="selectLabel" for="date-range">Only include movies released within</label>
<select is="emby-select" id="date-range" class="emby-select-withcolor emby-select">
<option value="3">Last 3 months</option>
<option value="6">Last 6 months</option>
<option value="12">Last 1 year</option>
<option value="24">Last 2 years</option>
<option value="0">All time (no limit)</option>
</select>
<div class="fieldDescription">
Applies to all sources. "Now Playing" and "Upcoming" already have tight date windows
set by TMDB, but this provides an additional filter.
</div>
</div>
</fieldset>
<!-- Download Settings -->
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend><h3 class="sectionTitle">Download Settings</h3></legend>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="download-folder">Output Folder</label>
<input type="text" id="download-folder" is="emby-input" placeholder="/media/trailers" />
<div class="fieldDescription">
Where the fake-movie/trailer folders are created. Add this as a Jellyfin Movies
library and scan it so a Cinema Mode / trailer pre-roll plugin can use the trailers.
</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="max-trailers">Max trailers per run</label>
<input type="number" id="max-trailers" is="emby-input" min="1" max="200" />
<div class="fieldDescription">
Maximum number of trailers to download each time the task runs. Default: 20.
</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="max-pages">Pages per source</label>
<input type="number" id="max-pages" is="emby-input" min="1" max="10" />
<div class="fieldDescription">
How many pages to fetch from each TMDB source (20 movies per page). Default: 3.
</div>
</div>
<div class="selectContainer">
<label class="selectLabel" for="video-quality">Video quality</label>
<select is="emby-select" id="video-quality" class="emby-select-withcolor emby-select">
<option value="720">720p (built-in, no extra tools)</option>
<option value="480">480p (built-in, no extra tools)</option>
<option value="1080">1080p (requires yt-dlp + ffmpeg)</option>
</select>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="skip-library" />
<span>Skip movies already in my Jellyfin library</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
Trailers for movies you already own won't be downloaded.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input is="emby-checkbox" type="checkbox" id="skip-downloaded" />
<span>Skip trailers already downloaded</span>
</label>
<div class="fieldDescription checkboxFieldDescription">
If a folder already exists for a movie, don't re-download it.
</div>
</div>
</fieldset>
<!-- Trailer Rotation -->
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend><h3 class="sectionTitle">Trailer Rotation</h3></legend>
<p class="fieldDescription">
Keep your trailer library fresh by automatically removing the oldest entries
each time the download task runs.
</p>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="max-total-trailers">Max trailers to keep</label>
<input type="number" id="max-total-trailers" is="emby-input" min="0" max="500" />
<div class="fieldDescription">
Maximum number of trailer folders to keep on disk at once. When this limit is exceeded,
the oldest are deleted first to make room for new downloads. Set to 0 for unlimited.
Default: 50.
</div>
</div>
</fieldset>
<!-- Advanced -->
<fieldset class="verticalSection verticalSection-extrabottompadding">
<legend><h3 class="sectionTitle">Advanced</h3></legend>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="ytdlp-path">yt-dlp path (optional)</label>
<input type="text" id="ytdlp-path" is="emby-input" placeholder="/usr/local/bin/yt-dlp" />
<div class="fieldDescription">
Full path to <a href="https://github.com/yt-dlp/yt-dlp" target="_blank" rel="noopener">yt-dlp</a>.
Required for 1080p quality. Also needs <strong>ffmpeg</strong> on the system PATH.
Leave blank to use the built-in downloader (720p max, zero extra tools).
</div>
</div>
</fieldset>
<br />
<button is="emby-button" type="submit" class="raised button-submit block">
<span>${Save}</span>
</button>
</form>
</div>
</div>
<script type="text/javascript">
var pluginId = "b581493e-1046-40ed-b6dc-cb8027624984";
$('.cinemaTrailers4JellyfinsConfigPage').on('pageshow', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(pluginId).then(function (config) {
document.getElementById('tmdb-api-key').value = config.TmdbApiKey || '';
document.getElementById('source-now-playing').checked = config.SourceNowPlaying !== false;
document.getElementById('source-upcoming').checked = config.SourceUpcoming !== false;
document.getElementById('source-popular').checked = !!config.SourcePopular;
document.getElementById('source-top-rated').checked = !!config.SourceTopRated;
document.getElementById('date-range').value = String(config.ReleaseDateRangeMonths ?? 6);
document.getElementById('download-folder').value = config.DownloadFolder || '';
document.getElementById('max-trailers').value = config.MaxTrailersToDownload ?? 20;
document.getElementById('max-pages').value = config.MaxPagesPerSource ?? 3;
document.getElementById('video-quality').value = String(config.PreferredVideoHeight ?? 720);
document.getElementById('skip-library').checked = config.SkipMoviesInLibrary !== false;
document.getElementById('skip-downloaded').checked = config.SkipAlreadyDownloaded !== false;
document.getElementById('ytdlp-path').value = config.YtDlpPath || '';
var langs = (config.AllowedLanguages || '').split(',').map(l => l.trim()).filter(Boolean);
['en','es','fr','de','it','pt','nl','ru','pl','sv','no','da','ja','ko','zh','ar','hi','tr','th','id']
.forEach(function(code) {
document.getElementById('lang-' + code).checked = langs.length === 0 || langs.indexOf(code) !== -1;
});
document.getElementById('max-total-trailers').value = config.MaxTotalTrailers ?? 50;
Dashboard.hideLoadingMsg();
});
});
$('.cinemaTrailers4JellyfinsConfigPage').on('submit', function () {
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(pluginId).then(function (config) {
config.TmdbApiKey = document.getElementById('tmdb-api-key').value;
config.SourceNowPlaying = document.getElementById('source-now-playing').checked;
config.SourceUpcoming = document.getElementById('source-upcoming').checked;
config.SourcePopular = document.getElementById('source-popular').checked;
config.SourceTopRated = document.getElementById('source-top-rated').checked;
config.ReleaseDateRangeMonths = parseInt(document.getElementById('date-range').value, 10);
config.DownloadFolder = document.getElementById('download-folder').value;
config.MaxTrailersToDownload = parseInt(document.getElementById('max-trailers').value, 10) || 20;
config.MaxPagesPerSource = parseInt(document.getElementById('max-pages').value, 10) || 3;
config.PreferredVideoHeight = parseInt(document.getElementById('video-quality').value, 10) || 720;
config.SkipMoviesInLibrary = document.getElementById('skip-library').checked;
config.SkipAlreadyDownloaded = document.getElementById('skip-downloaded').checked;
config.YtDlpPath = document.getElementById('ytdlp-path').value;
var allLangCodes = ['en','es','fr','de','it','pt','nl','ru','pl','sv','no','da','ja','ko','zh','ar','hi','tr','th','id'];
var checkedLangs = allLangCodes.filter(function(code) {
return document.getElementById('lang-' + code).checked;
});
// If all are checked treat it as "no preference" (empty string)
config.AllowedLanguages = checkedLangs.length === allLangCodes.length ? '' : checkedLangs.join(',');
config.MaxTotalTrailers = parseInt(document.getElementById('max-total-trailers').value, 10) || 50;
ApiClient.updatePluginConfiguration(pluginId, config)
.then(Dashboard.processPluginConfigurationUpdateResult);
});
return false;
});
</script>
</div>
</body>
</html>