Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 97 additions & 77 deletions Jellyfin.Plugin.FinTube/Api/FinTubeActivityController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,87 +71,107 @@ public ActionResult<Dictionary<string, object>> FinTubeDownload([FromBody] FinTu
_logger.LogInformation("FinTubeDownload : {ytid} to {targetfoldeer}, prefer free format: {preferfreeformat} audio only: {audioonly}", data.ytid, data.targetfolder, data.preferfreeformat, data.audioonly);

Dictionary<string, object> response = new Dictionary<string, object>();
PluginConfiguration? config = Plugin.Instance.Configuration;
String status = "";
PluginConfiguration? config = Plugin.Instance?.Configuration;


// check binaries
if(!System.IO.File.Exists(config.exec_YTDL))
throw new Exception("YT-DL Executable configured incorrectly");

bool hasid3v2 = System.IO.File.Exists(config.exec_ID3);


// Ensure proper / separator
data.targetfolder = String.Join("/", data.targetfolder.Split("/", StringSplitOptions.RemoveEmptyEntries));
String targetPath = data.targetlibrary.EndsWith("/") ? data.targetlibrary + data.targetfolder : data.targetlibrary + "/" + data.targetfolder;
// Create Folder if it doesn't exist
if(!System.IO.Directory.CreateDirectory(targetPath).Exists)
throw new Exception("Directory could not be created");


// Check for tags
bool hasTags = 1 < (data.title.Length + data.album.Length + data.artist.Length + data.track.ToString().Length);

// Save file with ytdlp as mp4 or mp3 depending on audioonly
String targetFilename;
String targetExtension = (data.preferfreeformat ? (data.audioonly ? @".opus" : @".webm") : (data.audioonly ? @".mp3" : @".mp4"));

if (!String.IsNullOrWhiteSpace(data.targetfilename))
targetFilename = System.IO.Path.Combine(targetPath, $"{data.targetfilename}");
else if (data.audioonly && hasTags && data.title.Length > 1) // Use title Tag for filename
targetFilename = System.IO.Path.Combine(targetPath, $"{data.title}");
else // Use YTID as filename
targetFilename = System.IO.Path.Combine(targetPath, $"{data.ytid}");

// Check if filename exists
if(System.IO.File.Exists(targetFilename))
throw new Exception($"File {targetFilename} already exists");

status += $"Filename: {targetFilename}<br>";

String args;
if(data.audioonly)
if (config != null)
{
args = "-x";
if(data.preferfreeformat)
args += " --prefer-free-format";
String status = "";

// check binaries
if(!System.IO.File.Exists(config.exec_YTDL))
throw new Exception("YT-DL Executable configured incorrectly");

bool hasid3v2 = System.IO.File.Exists(config.exec_ID3);


// Ensure proper / separator
data.targetfolder = String.Join("/", data.targetfolder.Split("/", StringSplitOptions.RemoveEmptyEntries));
String targetPath = data.targetlibrary.EndsWith("/") ? data.targetlibrary + data.targetfolder : data.targetlibrary + "/" + data.targetfolder;
// Create Folder if it doesn't exist
if(!System.IO.Directory.CreateDirectory(targetPath).Exists)
throw new Exception("Directory could not be created");


// Check for tags
bool hasTags = 1 < (data.title.Length + data.album.Length + data.artist.Length + data.track.ToString().Length);

// Save file with ytdlp as mp4 or mp3 depending on audioonly and free format preference
String targetFilename;
String targetExtension = (data.preferfreeformat ? (data.audioonly ? @".ogg" : @".webm") : (data.audioonly ? @".mp3" : @".mp4"));

if (!String.IsNullOrWhiteSpace(data.targetfilename))
targetFilename = System.IO.Path.Combine(targetPath, $"{data.targetfilename}");
else if (data.audioonly && hasTags && data.title.Length > 1) // Use title Tag for filename
targetFilename = System.IO.Path.Combine(targetPath, $"{data.title}");
else // Use YTID as filename
targetFilename = System.IO.Path.Combine(targetPath, $"{data.ytid}");

// Check if filename exists
if(System.IO.File.Exists(targetFilename))
throw new Exception($"File {targetFilename} already exists");

status += $"Filename: {targetFilename}<br>";

String args;
if(data.audioonly)
{
args = "-x";
if(data.preferfreeformat)
args += " --audio-format vorbis";
else
args += " --audio-format mp3";
args += $" -o \"{targetFilename}.%(ext)s\" -- {data.ytid}";
}
else
args += " --audio-format mp3";
args += $" -o \"{targetFilename}.%(ext)s\" {data.ytid}";
{
if(data.preferfreeformat)
args = "--prefer-free-format";
else
args = "-f mp4";
if(!string.IsNullOrEmpty(data.videoresolution))
args += $" -S res:{data.videoresolution}";
args += $" -o \"{targetFilename}-%(title)s.%(ext)s\" -- {data.ytid}";
}

status += $"Exec: {config.exec_YTDL} {args}<br>";

var procyt = createProcess(config.exec_YTDL, args);
procyt.Start();
procyt.WaitForExit();

// If audioonly and has tags
if (data.audioonly && hasTags)
{
Process? tagsProcess = null;
// Tag the mp3 file if id3v2
if (!data.preferfreeformat && hasid3v2)
{
args = $"-a \"{data.artist}\" -A \"{data.album}\" -t \"{data.title}\" -T \"{data.track}\" \"{targetFilename}{targetExtension}\"";

status += $"Exec: {config.exec_ID3} {args}<br>";

tagsProcess = createProcess(config.exec_ID3, args);
}
{
args = $"-w -t \"TITLE={data.title}\" -t \"ALBUM={data.album}\" -t \"TRACKNUMBER={data.track}\"";
foreach (var artist in data.artist.Split(';'))
{
args += $" -t \"ARTIST={artist}\"";
}
args += $" \"{targetFilename}{targetExtension}\"";

status += $"Exec: {config.exec_vorbiscomment} {args}<br>";

tagsProcess = createProcess(config.exec_vorbiscomment, args);
}
tagsProcess.Start();
tagsProcess.WaitForExit();
}

status += "<font color='green'>File Saved!</font>";

response.Add("message", status);
}
else
{
if(data.preferfreeformat)
args = "--prefer-free-format";
else
args = "-f mp4";
if(!string.IsNullOrEmpty(data.videoresolution))
args += $" -S res:{data.videoresolution}";
args += $" -o \"{targetFilename}-%(title)s.%(ext)s\" {data.ytid}";
}

status += $"Exec: {config.exec_YTDL} {args}<br>";

var procyt = createProcess(config.exec_YTDL, args);
procyt.Start();
procyt.WaitForExit();

// If audioonly AND id3v2 AND tags are set - Tag the mp3 file
if (data.audioonly && hasid3v2 && hasTags)
{
args = $"-a \"{data.artist}\" -A \"{data.album}\" -t \"{data.title}\" -T \"{data.track}\" \"{targetFilename}{targetExtension}\"";

status += $"Exec: {config.exec_ID3} {args}<br>";

var procid3 = createProcess(config.exec_ID3, args);
procid3.Start();
procid3.WaitForExit();
}

status += "<font color='green'>File Saved!</font>";

response.Add("message", status);
return Ok(response);
}
catch(Exception e)
Expand Down
6 changes: 6 additions & 0 deletions Jellyfin.Plugin.FinTube/Configuration/PluginConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public PluginConfiguration()
{
exec_YTDL = "/usr/local/bin/yt-dlp";
exec_ID3 = "/usr/bin/id3v2";
exec_vorbiscomment = "/usr/bin/vorbiscomment";
}

/// <summary>
Expand All @@ -25,4 +26,9 @@ public PluginConfiguration()
/// Executable for ID3v2
/// </summary>
public string exec_ID3 { get; set; }

/// <summary>
/// Executable for vorbiscomment
/// </summary>
public string exec_vorbiscomment { get; set; }
}
9 changes: 8 additions & 1 deletion Jellyfin.Plugin.FinTube/Configuration/configPage.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div class="content-primary">
<form id="FinTubeConfigForm">
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="exec_YTDL">Exec YT-DL</label>
<label class="inputLabel inputLabelUnfocused" for="exec_YTDL">Exec YT-DLP</label>
<input id="exec_YTDL" name="exec_YTDL" type="text" is="emby-input" />
<div class="fieldDescription">The executable filepath to youtube-dl/yt-dlp</div>
</div>
Expand All @@ -19,6 +19,11 @@
<input id="exec_ID3" name="exec_ID3" type="text" is="emby-input" />
<div class="fieldDescription">The executable filepath to id3v2</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="exec_vorbiscomment">Exec vorbiscomment</label>
<input id="exec_vorbiscomment" name="exec_vorbiscomment" type="text" is="emby-input" />
<div class="fieldDescription">The executable filepath to vorbiscomment</div>
</div>
<div>
<button is="emby-button" type="submit" class="raised button-submit block emby-button">
<span>Save</span>
Expand All @@ -38,6 +43,7 @@
ApiClient.getPluginConfiguration(TubeFinConfig.pluginUniqueId).then(function (config) {
document.querySelector('#exec_YTDL').value = config.exec_YTDL;
document.querySelector('#exec_ID3').value = config.exec_ID3;
document.querySelector('#exec_vorbiscomment').value = config.exec_vorbiscomment;
Dashboard.hideLoadingMsg();
});
});
Expand All @@ -48,6 +54,7 @@
ApiClient.getPluginConfiguration(TubeFinConfig.pluginUniqueId).then(function (config) {
config.exec_YTDL = document.querySelector('#exec_YTDL').value;
config.exec_ID3 = document.querySelector('#exec_ID3').value;
config.exec_vorbiscomment = document.querySelector('#exec_vorbiscomment').value;
ApiClient.updatePluginConfiguration(TubeFinConfig.pluginUniqueId, config).then(function (result) {
Dashboard.processPluginConfigurationUpdateResult(result);
});
Expand Down