#4 WIP
This commit is contained in:
parent
4abbf1162d
commit
dd2b7cd82c
@ -100,6 +100,9 @@ namespace OF_DL.Entities
|
||||
|
||||
[ToggleableConfig]
|
||||
public bool DisableBrowserAuth { get; set; } = false;
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public VideoResolution DownloadVideoResolution { get; set; } = VideoResolution.source;
|
||||
}
|
||||
|
||||
public class CreatorConfig : IFileNameFormatConfig
|
||||
|
@ -17,6 +17,8 @@ namespace OF_DL.Entities
|
||||
bool DownloadVideos { get; set; }
|
||||
bool DownloadAudios { get; set; }
|
||||
|
||||
VideoResolution DownloadVideoResolution { get; set; }
|
||||
|
||||
int? Timeout { get; set; }
|
||||
bool FolderPerPaidPost { get; set; }
|
||||
bool FolderPerPost { get; set; }
|
||||
|
@ -150,10 +150,10 @@ namespace OF_DL.Entities.Post
|
||||
public class VideoSources
|
||||
{
|
||||
[JsonProperty("720")]
|
||||
public object _720 { get; set; }
|
||||
public string _720 { get; set; }
|
||||
|
||||
[JsonProperty("240")]
|
||||
public object _240 { get; set; }
|
||||
public string _240 { get; set; }
|
||||
}
|
||||
public class Dash
|
||||
{
|
||||
|
15
OF DL/Enumerations/VideoResolution.cs
Normal file
15
OF DL/Enumerations/VideoResolution.cs
Normal 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
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ using OF_DL.Entities.Post;
|
||||
using OF_DL.Entities.Purchased;
|
||||
using OF_DL.Entities.Stories;
|
||||
using OF_DL.Entities.Streams;
|
||||
using OF_DL.Enumerations;
|
||||
using OF_DL.Enumurations;
|
||||
using Serilog;
|
||||
using Spectre.Console;
|
||||
@ -26,6 +27,7 @@ public class APIHelper : IAPIHelper
|
||||
{
|
||||
private static readonly JsonSerializerSettings m_JsonSerializerSettings;
|
||||
private readonly IDBHelper m_DBHelper;
|
||||
private readonly IDownloadConfig downloadConfig;
|
||||
private readonly Auth auth;
|
||||
private static DateTime? cachedDynamicRulesExpiration;
|
||||
private static DynamicRules? cachedDynamicRules;
|
||||
@ -42,6 +44,7 @@ public class APIHelper : IAPIHelper
|
||||
{
|
||||
this.auth = auth;
|
||||
m_DBHelper = new DBHelper(downloadConfig);
|
||||
this.downloadConfig = downloadConfig;
|
||||
}
|
||||
|
||||
|
||||
@ -1130,6 +1133,9 @@ public class APIHelper : IAPIHelper
|
||||
}
|
||||
if (medium.canView && medium.files?.drm == null)
|
||||
{
|
||||
switch (downloadConfig.DownloadVideoResolution)
|
||||
{
|
||||
case VideoResolution.source:
|
||||
if (medium.files!.full != null && !string.IsNullOrEmpty(medium.files!.full.url))
|
||||
{
|
||||
if (!medium.files!.full.url.Contains("upload"))
|
||||
@ -1142,18 +1148,37 @@ public class APIHelper : IAPIHelper
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (medium.files.preview != null && medium.files!.full == null)
|
||||
break;
|
||||
case VideoResolution._240:
|
||||
if(medium.videoSources != null)
|
||||
{
|
||||
if (!medium.files.preview.url.Contains("upload"))
|
||||
if (!string.IsNullOrEmpty(medium.videoSources._240))
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ using OF_DL.Enumerations;
|
||||
using OF_DL.Utils;
|
||||
using Org.BouncyCastle.Asn1.Tsp;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using Org.BouncyCastle.Tsp;
|
||||
using Serilog;
|
||||
using Spectre.Console;
|
||||
using System;
|
||||
@ -25,6 +26,7 @@ using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using static OF_DL.Entities.Lists.UserList;
|
||||
using static OF_DL.Entities.Messages.Messages;
|
||||
|
||||
@ -602,9 +604,30 @@ public class DownloadHelper : IDownloadHelper
|
||||
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}");
|
||||
|
||||
@ -1787,4 +1810,45 @@ public class DownloadHelper : IDownloadHelper
|
||||
return false;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +161,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(jsonConfig.DownloadVideoResolution == VideoResolution.source ? "source" : jsonConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -280,6 +281,7 @@ public class Program
|
||||
DownloadDateSelection = Enum.Parse<DownloadDateSelection>(hoconConfig.GetString("Download.DownloadDateSelection"), true),
|
||||
CustomDate = !string.IsNullOrWhiteSpace(hoconConfig.GetString("Download.CustomDate")) ? DateTime.Parse(hoconConfig.GetString("Download.CustomDate")) : null,
|
||||
ShowScrapeSize = hoconConfig.GetBoolean("Download.ShowScrapeSize"),
|
||||
DownloadVideoResolution = ParseVideoResolution(hoconConfig.GetString("Download.DownloadVideoResolution")),
|
||||
|
||||
// File Settings
|
||||
PaidPostFileNameFormat = hoconConfig.GetString("File.PaidPostFileNameFormat"),
|
||||
@ -399,6 +401,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{jsonConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{jsonConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {jsonConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(jsonConfig.DownloadVideoResolution == VideoResolution.source ? "source" : jsonConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -2862,6 +2865,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(newConfig.DownloadVideoResolution == VideoResolution.source ? "source" : newConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -3020,6 +3024,7 @@ public class Program
|
||||
hoconConfig.AppendLine($" DownloadDateSelection = \"{newConfig.DownloadDateSelection.ToString().ToLower()}\"");
|
||||
hoconConfig.AppendLine($" CustomDate = \"{newConfig.CustomDate?.ToString("yyyy-MM-dd")}\"");
|
||||
hoconConfig.AppendLine($" ShowScrapeSize = {newConfig.ShowScrapeSize.ToString().ToLower()}");
|
||||
hoconConfig.AppendLine($" DownloadVideoResolution = \"{(newConfig.DownloadVideoResolution == VideoResolution.source ? "source" : newConfig.DownloadVideoResolution.ToString().TrimStart('_'))}\"");
|
||||
hoconConfig.AppendLine("}");
|
||||
|
||||
hoconConfig.AppendLine("# File Settings");
|
||||
@ -3238,4 +3243,12 @@ public class Program
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user