This commit is contained in:
sim0n00ps 2025-05-06 00:34:15 +01:00
parent 4abbf1162d
commit dd2b7cd82c
7 changed files with 158 additions and 24 deletions

View File

@ -100,6 +100,9 @@ namespace OF_DL.Entities
[ToggleableConfig] [ToggleableConfig]
public bool DisableBrowserAuth { get; set; } = false; public bool DisableBrowserAuth { get; set; } = false;
[JsonConverter(typeof(StringEnumConverter))]
public VideoResolution DownloadVideoResolution { get; set; } = VideoResolution.source;
} }
public class CreatorConfig : IFileNameFormatConfig public class CreatorConfig : IFileNameFormatConfig

View File

@ -17,6 +17,8 @@ namespace OF_DL.Entities
bool DownloadVideos { get; set; } bool DownloadVideos { get; set; }
bool DownloadAudios { get; set; } bool DownloadAudios { get; set; }
VideoResolution DownloadVideoResolution { get; set; }
int? Timeout { get; set; } int? Timeout { get; set; }
bool FolderPerPaidPost { get; set; } bool FolderPerPaidPost { get; set; }
bool FolderPerPost { get; set; } bool FolderPerPost { get; set; }

View File

@ -150,10 +150,10 @@ namespace OF_DL.Entities.Post
public class VideoSources public class VideoSources
{ {
[JsonProperty("720")] [JsonProperty("720")]
public object _720 { get; set; } public string _720 { get; set; }
[JsonProperty("240")] [JsonProperty("240")]
public object _240 { get; set; } public string _240 { get; set; }
} }
public class Dash public class Dash
{ {

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OF_DL.Enumerations
{
public enum VideoResolution
{
_240,
_720,
source
}
}

View File

@ -9,6 +9,7 @@ using OF_DL.Entities.Post;
using OF_DL.Entities.Purchased; using OF_DL.Entities.Purchased;
using OF_DL.Entities.Stories; using OF_DL.Entities.Stories;
using OF_DL.Entities.Streams; using OF_DL.Entities.Streams;
using OF_DL.Enumerations;
using OF_DL.Enumurations; using OF_DL.Enumurations;
using Serilog; using Serilog;
using Spectre.Console; using Spectre.Console;
@ -26,6 +27,7 @@ public class APIHelper : IAPIHelper
{ {
private static readonly JsonSerializerSettings m_JsonSerializerSettings; private static readonly JsonSerializerSettings m_JsonSerializerSettings;
private readonly IDBHelper m_DBHelper; private readonly IDBHelper m_DBHelper;
private readonly IDownloadConfig downloadConfig;
private readonly Auth auth; private readonly Auth auth;
private static DateTime? cachedDynamicRulesExpiration; private static DateTime? cachedDynamicRulesExpiration;
private static DynamicRules? cachedDynamicRules; private static DynamicRules? cachedDynamicRules;
@ -42,6 +44,7 @@ public class APIHelper : IAPIHelper
{ {
this.auth = auth; this.auth = auth;
m_DBHelper = new DBHelper(downloadConfig); m_DBHelper = new DBHelper(downloadConfig);
this.downloadConfig = downloadConfig;
} }
@ -1130,29 +1133,51 @@ public class APIHelper : IAPIHelper
} }
if (medium.canView && medium.files?.drm == null) if (medium.canView && medium.files?.drm == null)
{ {
if (medium.files!.full != null && !string.IsNullOrEmpty(medium.files!.full.url)) switch (downloadConfig.DownloadVideoResolution)
{ {
if (!medium.files!.full.url.Contains("upload")) case VideoResolution.source:
{ if (medium.files!.full != null && !string.IsNullOrEmpty(medium.files!.full.url))
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
{ {
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files!.full.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null); if (!medium.files!.full.url.Contains("upload"))
singlePostCollection.SinglePosts.Add(medium.id, medium.files!.full.url); {
singlePostCollection.SinglePostMedia.Add(medium); if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
{
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files!.full.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
singlePostCollection.SinglePosts.Add(medium.id, medium.files!.full.url);
singlePostCollection.SinglePostMedia.Add(medium);
}
}
} }
} break;
} case VideoResolution._240:
else if (medium.files.preview != null && medium.files!.full == null) if(medium.videoSources != null)
{
if (!medium.files.preview.url.Contains("upload"))
{
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
{ {
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files.preview.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null); if (!string.IsNullOrEmpty(medium.videoSources._240))
singlePostCollection.SinglePosts.Add(medium.id, medium.files.preview.url); {
singlePostCollection.SinglePostMedia.Add(medium); if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
{
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.videoSources._240, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
singlePostCollection.SinglePosts.Add(medium.id, medium.videoSources._240);
singlePostCollection.SinglePostMedia.Add(medium);
}
}
} }
} break;
case VideoResolution._720:
if (medium.videoSources != null)
{
if (!string.IsNullOrEmpty(medium.videoSources._720))
{
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
{
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.videoSources._720, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
singlePostCollection.SinglePosts.Add(medium.id, medium.videoSources._720);
singlePostCollection.SinglePostMedia.Add(medium);
}
}
}
break;
} }
} }
else if (medium.canView && medium.files != null && medium.files.drm != null) else if (medium.canView && medium.files != null && medium.files.drm != null)
@ -1167,6 +1192,18 @@ public class APIHelper : IAPIHelper
} }
} }
} }
else if (medium.files.preview != null && medium.files!.full == null)
{
if (!medium.files.preview.url.Contains("upload"))
{
if (!singlePostCollection.SinglePosts.ContainsKey(medium.id))
{
await m_DBHelper.AddMedia(folder, medium.id, singlePost.id, medium.files.preview.url, null, null, null, "Posts", medium.type == "photo" ? "Images" : (medium.type == "video" || medium.type == "gif" ? "Videos" : (medium.type == "audio" ? "Audios" : null)), postPreviewIds.Contains((long)medium.id) ? true : false, false, null);
singlePostCollection.SinglePosts.Add(medium.id, medium.files.preview.url);
singlePostCollection.SinglePostMedia.Add(medium);
}
}
}
} }
} }
} }

View File

@ -12,6 +12,7 @@ using OF_DL.Enumerations;
using OF_DL.Utils; using OF_DL.Utils;
using Org.BouncyCastle.Asn1.Tsp; using Org.BouncyCastle.Asn1.Tsp;
using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Tsp;
using Serilog; using Serilog;
using Spectre.Console; using Spectre.Console;
using System; using System;
@ -25,6 +26,7 @@ using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq;
using static OF_DL.Entities.Lists.UserList; using static OF_DL.Entities.Lists.UserList;
using static OF_DL.Entities.Messages.Messages; using static OF_DL.Entities.Messages.Messages;
@ -602,9 +604,30 @@ public class DownloadHelper : IDownloadHelper
decKey = decryptionKey.Substring(pos1 + 1); decKey = decryptionKey.Substring(pos1 + 1);
} }
string tempFilename = $"{folder}{path}/{filename}_source.mp4"; int? streamIndex = await GetVideoStreamIndexFromMpd(url, policy, signature, kvp, downloadConfig.DownloadVideoResolution);
string parameters = $"-cenc_decryption_key {decKey} -headers \"Cookie:CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {sess} Origin: https://onlyfans.com Referer: https://onlyfans.com User-Agent: {user_agent}\" -y -i \"{url}\" -codec copy \"{tempFilename}\""; if (streamIndex == null)
throw new Exception($"Could not find video stream for resolution {downloadConfig.DownloadVideoResolution}");
string tempFilename;
switch (downloadConfig.DownloadVideoResolution)
{
case VideoResolution.source:
tempFilename = $"{folder}{path}/{filename}_source.mp4";
break;
case VideoResolution._240:
tempFilename = $"{folder}{path}/{filename}_240.mp4";
break;
case VideoResolution._720:
tempFilename = $"{folder}{path}/{filename}_720.mp4";
break;
default:
tempFilename = $"{folder}{path}/{filename}_source.mp4";
break;
}
string parameters = $"-cenc_decryption_key {decKey} -headers \"Cookie:CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {sess} Origin: https://onlyfans.com Referer: https://onlyfans.com User-Agent: {user_agent}\" -y -i \"{url}\" -map 0:v:{streamIndex} -map 0:a? -codec copy \"{tempFilename}\"";
Log.Debug($"Calling FFMPEG with Parameters: {parameters}"); Log.Debug($"Calling FFMPEG with Parameters: {parameters}");
@ -1787,4 +1810,45 @@ public class DownloadHelper : IDownloadHelper
return false; return false;
} }
#endregion #endregion
private async Task <int?> GetVideoStreamIndexFromMpd(string mpdUrl, string policy, string signature, string kvp, VideoResolution resolution)
{
HttpClient client = new();
HttpRequestMessage request = new(HttpMethod.Get, mpdUrl);
request.Headers.Add("user-agent", auth.USER_AGENT);
request.Headers.Add("Accept", "*/*");
request.Headers.Add("Cookie", $"CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {auth.COOKIE};");
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
XDocument doc = XDocument.Parse(body);
XNamespace ns = "urn:mpeg:dash:schema:mpd:2011";
XNamespace cenc = "urn:mpeg:cenc:2013";
var videoAdaptationSet = doc
.Descendants(ns + "AdaptationSet")
.FirstOrDefault(e => (string)e.Attribute("mimeType") == "video/mp4");
if (videoAdaptationSet == null)
return null;
string targetHeight = resolution switch
{
VideoResolution._240 => "240",
VideoResolution._720 => "720",
VideoResolution.source => "1280",
_ => throw new ArgumentOutOfRangeException(nameof(resolution))
};
var representations = videoAdaptationSet.Elements(ns + "Representation").ToList();
for (int i = 0; i < representations.Count; i++)
{
if ((string)representations[i].Attribute("height") == targetHeight)
return i; // this is the index FFmpeg will use for `-map 0:v:{i}`
}
}
return null;
}
} }

View File

@ -161,6 +161,7 @@ public class Program
hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\""); hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\"");
hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\""); hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}"); hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}");
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(jsonConfig.DownloadVideoResolution == VideoResolution.source ? "source" : jsonConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
hoconConfig.AppendLine("}"); hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# File Settings"); hoconConfig.AppendLine("# File Settings");
@ -280,9 +281,10 @@ public class Program
DownloadDateSelection = Enum.Parse<DownloadDateSelection>(hoconConfig.GetString("Download.DownloadDateSelection"), true), DownloadDateSelection = Enum.Parse<DownloadDateSelection>(hoconConfig.GetString("Download.DownloadDateSelection"), true),
CustomDate = !string.IsNullOrWhiteSpace(hoconConfig.GetString("Download.CustomDate")) ? DateTime.Parse(hoconConfig.GetString("Download.CustomDate")) : null, CustomDate = !string.IsNullOrWhiteSpace(hoconConfig.GetString("Download.CustomDate")) ? DateTime.Parse(hoconConfig.GetString("Download.CustomDate")) : null,
ShowScrapeSize = hoconConfig.GetBoolean("Download.ShowScrapeSize"), ShowScrapeSize = hoconConfig.GetBoolean("Download.ShowScrapeSize"),
DownloadVideoResolution = ParseVideoResolution(hoconConfig.GetString("Download.DownloadVideoResolution")),
// File Settings // File Settings
PaidPostFileNameFormat = hoconConfig.GetString("File.PaidPostFileNameFormat"), PaidPostFileNameFormat = hoconConfig.GetString("File.PaidPostFileNameFormat"),
PostFileNameFormat = hoconConfig.GetString("File.PostFileNameFormat"), PostFileNameFormat = hoconConfig.GetString("File.PostFileNameFormat"),
PaidMessageFileNameFormat = hoconConfig.GetString("File.PaidMessageFileNameFormat"), PaidMessageFileNameFormat = hoconConfig.GetString("File.PaidMessageFileNameFormat"),
MessageFileNameFormat = hoconConfig.GetString("File.MessageFileNameFormat"), MessageFileNameFormat = hoconConfig.GetString("File.MessageFileNameFormat"),
@ -399,6 +401,7 @@ public class Program
hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\""); hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\"");
hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\""); hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}"); hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}");
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(jsonConfig.DownloadVideoResolution == VideoResolution.source ? "source" : jsonConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
hoconConfig.AppendLine("}"); hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# File Settings"); hoconConfig.AppendLine("# File Settings");
@ -2862,6 +2865,7 @@ public class Program
hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\""); hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\"");
hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\""); hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}"); hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}");
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(newConfig.DownloadVideoResolution == VideoResolution.source ? "source" : newConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
hoconConfig.AppendLine("}"); hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# File Settings"); hoconConfig.AppendLine("# File Settings");
@ -3020,6 +3024,7 @@ public class Program
hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\""); hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\"");
hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\""); hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}"); hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}");
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(newConfig.DownloadVideoResolution == VideoResolution.source ? "source" : newConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
hoconConfig.AppendLine("}"); hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# File Settings"); hoconConfig.AppendLine("# File Settings");
@ -3238,4 +3243,12 @@ public class Program
Environment.Exit(2); Environment.Exit(2);
} }
} }
public static VideoResolution ParseVideoResolution(string value)
{
if (value.Equals("source", StringComparison.OrdinalIgnoreCase))
return VideoResolution.source;
return Enum.Parse<VideoResolution>("_" + value, ignoreCase: true);
}
} }