mirror of
https://github.com/fiso64/slsk-batchdl.git
synced 2024-12-22 14:32:40 +00:00
--strict
This commit is contained in:
parent
78177932ee
commit
39eccadd2e
2 changed files with 82 additions and 59 deletions
30
README.md
30
README.md
|
@ -2,40 +2,42 @@
|
||||||
|
|
||||||
A batch downloader for Soulseek built with Soulseek.NET. Accepts CSV files or Spotify and YouTube urls.
|
A batch downloader for Soulseek built with Soulseek.NET. Accepts CSV files or Spotify and YouTube urls.
|
||||||
|
|
||||||
#### Download tracks from a csv file:
|
## Examples
|
||||||
|
|
||||||
|
### Download tracks from a csv file:
|
||||||
```
|
```
|
||||||
slsk-batchdl test.csv
|
slsk-batchdl test.csv
|
||||||
```
|
```
|
||||||
Use `--print tracks` before downloading to check if everything has been parsed correctly. The names of the columns in the csv should be: `Artist`, `Title`, `Album`, `Length`, though alternative names are sometimes inferred as well. Only the title column is required, but any additional info improves search results.
|
The names of the columns in the csv should be: `Artist`, `Title`, `Album`, `Length`, though alternatives can sometimes be inferred as well. You can use `--print tracks` before downloading to check if everything has been parsed correctly. Only the title column is required, but any additional info improves search results.
|
||||||
|
|
||||||
#### Download spotify likes while skipping existing songs:
|
### Download spotify likes while skipping existing songs:
|
||||||
```
|
```
|
||||||
slsk-batchdl spotify-likes --skip-existing
|
slsk-batchdl spotify-likes --skip-existing
|
||||||
```
|
```
|
||||||
To download private playlists or liked songs you will need to provide a client id and secret, which you can get here https://developer.spotify.com/dashboard/applications. Create an app and add `http://localhost:48721/callback` as a redirect url in its settings.
|
To download private playlists or liked songs you will need to provide a client id and secret, which you can get here https://developer.spotify.com/dashboard/applications. Create an app and add `http://localhost:48721/callback` as a redirect url in its settings.
|
||||||
|
|
||||||
#### Download youtube playlist (with fallback to yt-dlp), including deleted videos:
|
### Download from youtube playlist (w. yt-dlp fallback), including deleted videos:
|
||||||
```
|
```
|
||||||
slsk-batchdl --get-deleted --yt-dlp "https://www.youtube.com/playlist?list=PLI_eFW8NAFzYAXZ5DrU6E6mQ_XfhaLBUX"
|
slsk-batchdl --get-deleted --yt-dlp "https://www.youtube.com/playlist?list=PLI_eFW8NAFzYAXZ5DrU6E6mQ_XfhaLBUX"
|
||||||
```
|
```
|
||||||
Playlists are retrieved using the YoutubeExplode library which unfortunately doesn't always return all videos. You can use the official API by providing a key with `--youtube-key`. Get it here https://console.cloud.google.com. Create a new project, click "Enable Api" and search for "youtube data", then follow the prompts.
|
Playlists are retrieved using the YoutubeExplode library which unfortunately doesn't always return all videos. You can use the official API by providing a key with `--youtube-key`. Get it here https://console.cloud.google.com. Create a new project, click "Enable Api" and search for "youtube data", then follow the prompts.
|
||||||
|
|
||||||
#### Search & download a specific song:
|
### Search & download a specific song:
|
||||||
```
|
```
|
||||||
slsk-batchdl "title=MC MENTAL @ HIS BEST,length=242" --pref-format "flac,wav"
|
slsk-batchdl "title=MC MENTAL @ HIS BEST,length=242" --pref-format "flac,wav"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Interactive album download:
|
### Interactive album download:
|
||||||
```
|
```
|
||||||
slsk-batchdl "album=Some Album" --interactive
|
slsk-batchdl "album=Some Album" --interactive
|
||||||
```
|
```
|
||||||
|
|
||||||
#### See which songs by an artist are missing in your library:
|
### Find an artist's songs that aren't in your library:
|
||||||
```
|
```
|
||||||
slsk-batchdl "artist=MC MENTAL" --aggregate --print tracks-full --skip-existing --music-dir "path\to\music"
|
slsk-batchdl "artist=MC MENTAL" --aggregate --print tracks-full --skip-existing --music-dir "path\to\music"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options
|
## Options
|
||||||
```
|
```
|
||||||
Usage: slsk-batchdl <input> [OPTIONS]
|
Usage: slsk-batchdl <input> [OPTIONS]
|
||||||
|
|
||||||
|
@ -107,6 +109,9 @@ Options:
|
||||||
--pref-max-samplerate <rate> Preferred maximum sample rate (default: 96000)
|
--pref-max-samplerate <rate> Preferred maximum sample rate (default: 96000)
|
||||||
--pref-strict-artist Prefer download if filepath contains track artist
|
--pref-strict-artist Prefer download if filepath contains track artist
|
||||||
--pref-banned-users <list> Comma-separated list of users to deprioritize
|
--pref-banned-users <list> Comma-separated list of users to deprioritize
|
||||||
|
--strict Skip files with missing properties instead of accepting by
|
||||||
|
default; if --min-bitrate is set, ignores any files with
|
||||||
|
unknown bitrate.
|
||||||
|
|
||||||
-a --aggregate When input is a string: Instead of downloading a single
|
-a --aggregate When input is a string: Instead of downloading a single
|
||||||
track matching the search string, find and download all
|
track matching the search string, find and download all
|
||||||
|
@ -122,7 +127,7 @@ Options:
|
||||||
--interactive When downloading albums: Allows to select the wanted album
|
--interactive When downloading albums: Allows to select the wanted album
|
||||||
--album-track-count <num> Specify the exact number of tracks in the album. Folders
|
--album-track-count <num> Specify the exact number of tracks in the album. Folders
|
||||||
with a different number of tracks will be ignored. Append
|
with a different number of tracks will be ignored. Append
|
||||||
a '+' or '-' to the number for the inequalities >= and <=.
|
a '+' or '-' after the number for the inequalities >= and <=
|
||||||
--album-ignore-fails When downloading an album and one of the files fails, do not
|
--album-ignore-fails When downloading an album and one of the files fails, do not
|
||||||
skip to the next source and do not delete all successfully
|
skip to the next source and do not delete all successfully
|
||||||
downloaded files
|
downloaded files
|
||||||
|
@ -179,17 +184,18 @@ Options:
|
||||||
'results-full': Print search results including full paths
|
'results-full': Print search results including full paths
|
||||||
--debug Print extra debug info
|
--debug Print extra debug info
|
||||||
```
|
```
|
||||||
|
### File conditions:
|
||||||
Files not satisfying the conditions will not be downloaded. For example, `--length-tol` is set to 3 by default, meaning that files whose duration differs from the supplied duration by more than 3 seconds will not be downloaded (disable it by setting it to 99999).
|
Files not satisfying the conditions will not be downloaded. For example, `--length-tol` is set to 3 by default, meaning that files whose duration differs from the supplied duration by more than 3 seconds will not be downloaded (disable it by setting it to 99999).
|
||||||
Files satisfying `pref-` conditions will be preferred. For example, setting `--pref-format "flac,wav"` will make it download high quality files if they exist and only download low quality files if there's nothing else.
|
Files satisfying `pref-` conditions will be preferred. For example, setting `--pref-format "flac,wav"` will make it download high quality files if they exist and only download low quality files if there's nothing else.
|
||||||
|
|
||||||
#### Name format:
|
### Name format:
|
||||||
Available tags are: artist, artists, album_artist, album_artists, title, album, year, track, disc, filename, default_foldername. Name format supports subdirectories as well as conditional expressions: `{str1|str2}` – If any tags in str1 are null, choose str2. String literals enclosed in parentheses are ignored in the null check.
|
Available tags are: artist, artists, album_artist, album_artists, title, album, year, track, disc, filename, default_foldername. Name format supports subdirectories as well as conditional expressions: `{str1|str2}` – If any tags in str1 are null, choose str2. String literals enclosed in parentheses are ignored in the null check.
|
||||||
```
|
```
|
||||||
{artist( - )title|album_artist( - )title|filename}
|
{artist( - )title|album_artist( - )title|filename}
|
||||||
{album(/)}{track(. )}{artist|(unknown artist)} - {title|(unknown title)}
|
{album(/)}{track(. )}{artist|(unknown artist)} - {title|(unknown title)}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration files
|
## Configuration files
|
||||||
Create a file named `slsk-batchdl.conf` in the same directory as the executable and write your arguments there, e.g:
|
Create a file named `slsk-batchdl.conf` in the same directory as the executable and write your arguments there, e.g:
|
||||||
```
|
```
|
||||||
--username "fakename"
|
--username "fakename"
|
||||||
|
@ -197,7 +203,7 @@ Create a file named `slsk-batchdl.conf` in the same directory as the executable
|
||||||
--pref-format "flac"
|
--pref-format "flac"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Notes
|
## Notes
|
||||||
- For macOS builds you can use publish.sh to build the app. Download dotnet from https://dotnet.microsoft.com/en-us/download/dotnet/6.0, then run `chmod +x publish.sh && sh publish.sh`
|
- For macOS builds you can use publish.sh to build the app. Download dotnet from https://dotnet.microsoft.com/en-us/download/dotnet/6.0, then run `chmod +x publish.sh && sh publish.sh`
|
||||||
- The CSV file must use `"` as string delimiter and be encoded with UTF8.
|
- The CSV file must use `"` as string delimiter and be encoded with UTF8.
|
||||||
- `--display single` and especially `double` can cause the printed lines to be duplicated or overwritten on some configurations. Use `simple` if that's an issue.
|
- `--display single` and especially `double` can cause the printed lines to be duplicated or overwritten on some configurations. Use `simple` if that's an issue.
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Soulseek;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using TagLib;
|
||||||
|
|
||||||
using ProgressBar = Konsole.ProgressBar;
|
using ProgressBar = Konsole.ProgressBar;
|
||||||
using SearchResponse = Soulseek.SearchResponse;
|
using SearchResponse = Soulseek.SearchResponse;
|
||||||
|
@ -159,7 +160,6 @@ static class Program
|
||||||
|
|
||||||
static object consoleLock = new object();
|
static object consoleLock = new object();
|
||||||
|
|
||||||
static DateTime lastUpdate;
|
|
||||||
static bool skipUpdate = false;
|
static bool skipUpdate = false;
|
||||||
static bool debugDisableDownload = false;
|
static bool debugDisableDownload = false;
|
||||||
static bool debugPrintTracks = false;
|
static bool debugPrintTracks = false;
|
||||||
|
@ -265,6 +265,9 @@ static class Program
|
||||||
"\n --pref-max-samplerate <rate> Preferred maximum sample rate (default: 96000)" +
|
"\n --pref-max-samplerate <rate> Preferred maximum sample rate (default: 96000)" +
|
||||||
"\n --pref-strict-artist Prefer download if filepath contains track artist" +
|
"\n --pref-strict-artist Prefer download if filepath contains track artist" +
|
||||||
"\n --pref-banned-users <list> Comma-separated list of users to deprioritize" +
|
"\n --pref-banned-users <list> Comma-separated list of users to deprioritize" +
|
||||||
|
"\n --strict Skip files with missing properties instead of accepting by" +
|
||||||
|
"\n default; if --min-bitrate is set, ignores any files with" +
|
||||||
|
"\n unknown bitrate." +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\n -a --aggregate When input is a string: Instead of downloading a single" +
|
"\n -a --aggregate When input is a string: Instead of downloading a single" +
|
||||||
"\n track matching the search string, find and download all" +
|
"\n track matching the search string, find and download all" +
|
||||||
|
@ -280,7 +283,7 @@ static class Program
|
||||||
"\n --interactive When downloading albums: Allows to select the wanted album" +
|
"\n --interactive When downloading albums: Allows to select the wanted album" +
|
||||||
"\n --album-track-count <num> Specify the exact number of tracks in the album. Folders" +
|
"\n --album-track-count <num> Specify the exact number of tracks in the album. Folders" +
|
||||||
"\n with a different number of tracks will be ignored. Append" +
|
"\n with a different number of tracks will be ignored. Append" +
|
||||||
"\n a '+' or '-' to the number for the inequalities >= and <=." +
|
"\n a '+' or '-' after the number for the inequalities >= and <=" +
|
||||||
"\n --album-ignore-fails When downloading an album and one of the files fails, do not" +
|
"\n --album-ignore-fails When downloading an album and one of the files fails, do not" +
|
||||||
"\n skip to the next source and do not delete all successfully" +
|
"\n skip to the next source and do not delete all successfully" +
|
||||||
"\n downloaded files" +
|
"\n downloaded files" +
|
||||||
|
@ -359,7 +362,7 @@ static class Program
|
||||||
}
|
}
|
||||||
|
|
||||||
bool confPathChanged = false;
|
bool confPathChanged = false;
|
||||||
int idx = Array.IndexOf(args, "--config");
|
int idx = Array.LastIndexOf(args, "--config");
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
{
|
{
|
||||||
confPath = args[idx + 1];
|
confPath = args[idx + 1];
|
||||||
|
@ -375,6 +378,18 @@ static class Program
|
||||||
args = finalArgs.ToArray();
|
args = finalArgs.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args.Contains("--strict"))
|
||||||
|
{
|
||||||
|
preferredCond.AcceptMissingProps = false;
|
||||||
|
necessaryCond.AcceptMissingProps = false;
|
||||||
|
preferredCond.MaxBitrate = -1;
|
||||||
|
necessaryCond.MaxBitrate = -1;
|
||||||
|
preferredCond.MinBitrate = -1;
|
||||||
|
necessaryCond.MinBitrate = -1;
|
||||||
|
preferredCond.MaxSampleRate = -1;
|
||||||
|
necessaryCond.MaxSampleRate = -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < args.Length; i++)
|
for (int i = 0; i < args.Length; i++)
|
||||||
{
|
{
|
||||||
if (args[i].StartsWith("-"))
|
if (args[i].StartsWith("-"))
|
||||||
|
@ -693,6 +708,10 @@ static class Program
|
||||||
case "--debug":
|
case "--debug":
|
||||||
debugInfo = true;
|
debugInfo = true;
|
||||||
break;
|
break;
|
||||||
|
case "--strict":
|
||||||
|
preferredCond.AcceptMissingProps = false;
|
||||||
|
necessaryCond.AcceptMissingProps = false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException($"Unknown argument: {args[i]}");
|
throw new ArgumentException($"Unknown argument: {args[i]}");
|
||||||
}
|
}
|
||||||
|
@ -1475,7 +1494,7 @@ static class Program
|
||||||
{
|
{
|
||||||
foreach (var res in ytResults)
|
foreach (var res in ytResults)
|
||||||
{
|
{
|
||||||
if (necessaryCond.LengthToleranceSatisfies(track, res.length))
|
if (necessaryCond.LengthToleranceSatisfies(res.length, track.Length))
|
||||||
{
|
{
|
||||||
string saveFilePathNoExt = GetSavePathNoExt(res.title, track);
|
string saveFilePathNoExt = GetSavePathNoExt(res.title, track);
|
||||||
downloading = true;
|
downloading = true;
|
||||||
|
@ -1802,9 +1821,9 @@ static class Program
|
||||||
.ThenByDescending(x => preferredCond.FileSatisfies(x.file, track, x.response))
|
.ThenByDescending(x => preferredCond.FileSatisfies(x.file, track, x.response))
|
||||||
.ThenByDescending(x => x.response.HasFreeUploadSlot)
|
.ThenByDescending(x => x.response.HasFreeUploadSlot)
|
||||||
.ThenByDescending(x => x.response.UploadSpeed / 600)
|
.ThenByDescending(x => x.response.UploadSpeed / 600)
|
||||||
.ThenByDescending(x => albumMode || FileConditions.StrictString(x.file.Filename, track.TrackTitle))
|
.ThenByDescending(x => albumMode || FileConditions.StrictString(x.file.Filename, track.TrackTitle, ignoreCase: true))
|
||||||
.ThenByDescending(x => !albumMode || FileConditions.StrictString(GetDirectoryNameSlsk(x.file.Filename), track.Album))
|
.ThenByDescending(x => !albumMode || FileConditions.StrictString(GetDirectoryNameSlsk(x.file.Filename), track.Album, ignoreCase: true))
|
||||||
.ThenByDescending(x => FileConditions.StrictString(x.file.Filename, track.ArtistName))
|
.ThenByDescending(x => FileConditions.StrictString(x.file.Filename, track.ArtistName, ignoreCase: true))
|
||||||
.ThenByDescending(x => !useLevenshtein || levenshtein(x) <= 5)
|
.ThenByDescending(x => !useLevenshtein || levenshtein(x) <= 5)
|
||||||
.ThenByDescending(x => x.response.UploadSpeed / 300)
|
.ThenByDescending(x => x.response.UploadSpeed / 300)
|
||||||
.ThenByDescending(x => (x.file.BitRate ?? 0) / 70)
|
.ThenByDescending(x => (x.file.BitRate ?? 0) / 70)
|
||||||
|
@ -2140,8 +2159,6 @@ static class Program
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
lastUpdate = DateTime.Now;
|
|
||||||
|
|
||||||
if (!skipUpdate)
|
if (!skipUpdate)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -2329,6 +2346,7 @@ static class Program
|
||||||
public string StrictStringRegexRemove = "";
|
public string StrictStringRegexRemove = "";
|
||||||
public bool StrictStringDiacrRemove = true;
|
public bool StrictStringDiacrRemove = true;
|
||||||
public bool AcceptNoLength = false;
|
public bool AcceptNoLength = false;
|
||||||
|
public bool AcceptMissingProps = true;
|
||||||
|
|
||||||
public FileConditions() { }
|
public FileConditions() { }
|
||||||
|
|
||||||
|
@ -2394,7 +2412,7 @@ static class Program
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fname = noPath ? GetFileNameWithoutExtSlsk(fname) : fname;
|
fname = noPath ? GetFileNameWithoutExtSlsk(fname) : fname;
|
||||||
return StrictString(fname, tname, StrictStringRegexRemove, StrictStringDiacrRemove);
|
return StrictString(fname, tname, StrictStringRegexRemove, StrictStringDiacrRemove, ignoreCase: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StrictArtistSatisfies(string fname, string aname)
|
public bool StrictArtistSatisfies(string fname, string aname)
|
||||||
|
@ -2402,7 +2420,7 @@ static class Program
|
||||||
if (!StrictArtist || aname == "")
|
if (!StrictArtist || aname == "")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return StrictString(fname, aname, StrictStringRegexRemove, StrictStringDiacrRemove);
|
return StrictString(fname, aname, StrictStringRegexRemove, StrictStringDiacrRemove, ignoreCase: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StrictAlbumSatisfies(string fname, string alname)
|
public bool StrictAlbumSatisfies(string fname, string alname)
|
||||||
|
@ -2410,10 +2428,10 @@ static class Program
|
||||||
if (!StrictAlbum || alname == "")
|
if (!StrictAlbum || alname == "")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return StrictString(GetDirectoryNameSlsk(fname), alname, StrictStringRegexRemove, StrictStringDiacrRemove);
|
return StrictString(GetDirectoryNameSlsk(fname), alname, StrictStringRegexRemove, StrictStringDiacrRemove, ignoreCase: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool StrictString(string fname, string tname, string regexRemove = "", bool diacrRemove = true, bool ignoreCase = false)
|
public static bool StrictString(string fname, string tname, string regexRemove = "", bool diacrRemove = true, bool ignoreCase = true)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(tname))
|
if (string.IsNullOrEmpty(tname))
|
||||||
return true;
|
return true;
|
||||||
|
@ -2436,66 +2454,65 @@ static class Program
|
||||||
return Formats.Length == 0 || (ext != "" && Formats.Any(f => f == ext));
|
return Formats.Length == 0 || (ext != "" && Formats.Any(f => f == ext));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LengthToleranceSatisfies(Soulseek.File file, int actualLength)
|
public bool LengthToleranceSatisfies(Soulseek.File file, int wantedLength)
|
||||||
{
|
{
|
||||||
if (LengthTolerance < 0 || actualLength < 0)
|
return LengthToleranceSatisfies(file.Length, wantedLength);
|
||||||
return true;
|
|
||||||
if (file.Length == null)
|
|
||||||
return AcceptNoLength;
|
|
||||||
return Math.Abs((int)file.Length - actualLength) <= LengthTolerance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LengthToleranceSatisfies(TagLib.File file, int actualLength)
|
public bool LengthToleranceSatisfies(TagLib.File file, int wantedLength)
|
||||||
{
|
{
|
||||||
if (LengthTolerance < 0 || actualLength < 0)
|
return LengthToleranceSatisfies((int)file.Properties.Duration.TotalSeconds, wantedLength);
|
||||||
return true;
|
|
||||||
int fileLength = (int)file.Properties.Duration.TotalSeconds;
|
|
||||||
if (Math.Abs(fileLength - actualLength) <= LengthTolerance)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LengthToleranceSatisfies(Track track, int actualLength)
|
public bool LengthToleranceSatisfies(int? length, int wantedLength)
|
||||||
{
|
{
|
||||||
if (LengthTolerance < 0 || actualLength < 0 || track.Length < 0)
|
if (LengthTolerance < 0 || wantedLength < 0)
|
||||||
return true;
|
return true;
|
||||||
if (Math.Abs(track.Length - actualLength) <= LengthTolerance)
|
if (length == null || length < 0)
|
||||||
return true;
|
return AcceptNoLength && AcceptMissingProps;
|
||||||
return false;
|
return Math.Abs((int)length - wantedLength) <= LengthTolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BitrateSatisfies(Soulseek.File file)
|
public bool BitrateSatisfies(Soulseek.File file)
|
||||||
{
|
{
|
||||||
if ((MinBitrate < 0 && MaxBitrate < 0) || file.BitRate == null)
|
return BitrateSatisfies(file.BitRate);
|
||||||
return true;
|
|
||||||
if (MinBitrate >= 0 && file.BitRate.Value < MinBitrate)
|
|
||||||
return false;
|
|
||||||
if (MaxBitrate >= 0 && file.BitRate.Value > MaxBitrate)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BitrateSatisfies(TagLib.File file)
|
public bool BitrateSatisfies(TagLib.File file)
|
||||||
{
|
{
|
||||||
if ((MinBitrate < 0 && MaxBitrate < 0) || file.Properties.AudioBitrate <= 0)
|
return BitrateSatisfies(file.Properties.AudioBitrate);
|
||||||
return true;
|
}
|
||||||
if (MinBitrate >= 0 && file.Properties.AudioBitrate < MinBitrate)
|
|
||||||
return false;
|
|
||||||
if (MaxBitrate >= 0 && file.Properties.AudioBitrate > MaxBitrate)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
public bool BitrateSatisfies(int? bitrate)
|
||||||
|
{
|
||||||
|
if (MinBitrate < 0 && MaxBitrate < 0)
|
||||||
|
return true;
|
||||||
|
if (bitrate == null || bitrate < 0)
|
||||||
|
return AcceptMissingProps;
|
||||||
|
if (MinBitrate >= 0 && bitrate < MinBitrate)
|
||||||
|
return false;
|
||||||
|
if (MaxBitrate >= 0 && bitrate > MaxBitrate)
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SampleRateSatisfies(Soulseek.File file)
|
public bool SampleRateSatisfies(Soulseek.File file)
|
||||||
{
|
{
|
||||||
return MaxSampleRate < 0 || file.SampleRate == null || file.SampleRate.Value <= MaxSampleRate;
|
return SampleRateSatisfies(file.SampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SampleRateSatisfies(TagLib.File file)
|
public bool SampleRateSatisfies(TagLib.File file)
|
||||||
{
|
{
|
||||||
return MaxSampleRate < 0 || file.Properties.AudioSampleRate <= MaxSampleRate;
|
return SampleRateSatisfies(file.Properties.AudioSampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SampleRateSatisfies(int? sampleRate)
|
||||||
|
{
|
||||||
|
if (MaxSampleRate < 0)
|
||||||
|
return true;
|
||||||
|
if (sampleRate == null || sampleRate < 0)
|
||||||
|
return AcceptMissingProps;
|
||||||
|
return sampleRate <= MaxSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BannedUsersSatisfies(SearchResponse? response)
|
public bool BannedUsersSatisfies(SearchResponse? response)
|
||||||
|
|
Loading…
Reference in a new issue