Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加自定义 ffmpeg metadata #801

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
73 changes: 72 additions & 1 deletion BBDown/BBDownMuxer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using static BBDown.Core.Entity.Entity;
using static BBDown.BBDownUtil;
using static BBDown.Core.Util.SubUtil;
Expand Down Expand Up @@ -95,7 +96,10 @@ private static int MuxByMp4box(string videoPath, string audioPath, string outPat
return RunExe(MP4BOX, arguments, MP4BOX != "mp4box");
}

public static int MuxAV(bool useMp4box, string videoPath, string audioPath, List<AudioMaterial> audioMaterial, string outPath, string desc = "", string title = "", string author = "", string episodeId = "", string pic = "", string lang = "", List<Subtitle>? subs = null, bool audioOnly = false, bool videoOnly = false, List<ViewPoint>? points = null, long pubTime = 0, bool simplyMux = false)
public static int MuxAV(bool useMp4box, string videoPath, string audioPath, List<AudioMaterial> audioMaterial, string outPath,
string desc = "", string title = "", string author = "", string episodeId = "", string pic = "", string lang = "", List<Subtitle>? subs = null,
bool audioOnly = false, bool videoOnly = false, List<ViewPoint>? points = null,
long pubTime = 0, bool simplyMux = false, MyOption myOption = null,Page p = null,int pagesCount = 0)
{
if (audioOnly && audioPath != "")
videoPath = "";
Expand Down Expand Up @@ -185,6 +189,35 @@ public static int MuxAV(bool useMp4box, string videoPath, string audioPath, List
if (episodeId != "") argsBuilder.Append($"-metadata album=\"{title}\" ");
if (pubTime != 0) argsBuilder.Append($"-metadata creation_time=\"{(DateTimeOffset.FromUnixTimeSeconds(pubTime).ToString("yyyy-MM-ddTHH:mm:ss.ffffffZ"))}\" ");
}
if (myOption.FfmpegMetadata != "") {
Regex regex = new Regex(@"-metadata (\w+)=(.*?)(?=-metadata|$)", RegexOptions.Singleline);
MatchCollection matches = regex.Matches(argsBuilder.ToString());
string metadata = myOption.FfmpegMetadata;
foreach (Match match in matches)
{
if (match.Success)
{
string key = match.Groups[1].Value;
string value = FormatValue(GetValueForReplacement(key, metadata),title,p,pagesCount);
if (!string.IsNullOrEmpty(value))
{
argsBuilder.Replace($"{key}={match.Groups[2].Value}", $"{key}=\"{value}\" ");
metadata = metadata.Replace($"{key}={value}","");
}
}
}
string[] keyValuePairs = metadata.Split(',');
foreach (var keyValuePair in keyValuePairs)
{
string[] parts = keyValuePair.Split('=');
if (parts.Length == 2)
{
string key = parts[0];
string value = FormatValue(parts[1], title, p, pagesCount);
argsBuilder.Append($"-metadata {key}=\"{value}\" ");
}
}
}
argsBuilder.Append("-c copy ");
if (audioOnly && audioPath == "") argsBuilder.Append("-vn ");
if (subs != null) argsBuilder.Append("-c:s mov_text ");
Expand Down Expand Up @@ -217,5 +250,43 @@ public static void MergeFLV(string[] files, string outPath)
foreach (var s in f) File.Delete(s);
}
}

private static string GetValueForReplacement(string key, string input)
{
Regex regex = new Regex($"{key}=([^,]+)");
Match match = regex.Match(input);

if (match.Success)
{
return match.Groups[1].Value;
}
else
{
return string.Empty;
}
}

private static string FormatValue(string value,string title,Page p,int pagesCount) {
var regex = Program.InfoRegex();
foreach (Match m in regex.Matches(value).Cast<Match>())
{
var key = m.Groups[1].Value;
var v = key switch
{
"videoTitle" => BBDownUtil.GetValidFileName(title, filterSlash: true).Trim().TrimEnd('.').Trim(),
"pageNumber" => p.index.ToString(),
"pageNumberWithZero" => p.index.ToString().PadLeft(pagesCount.ToString().Length, '0'),
"pageTitle" => BBDownUtil.GetValidFileName(p.title, filterSlash: true).Trim().TrimEnd('.').Trim(),
"bvid" => p.bvid,
"aid" => p.aid,
"cid" => p.cid,
"ownerName" => p.ownerName == null ? "" : BBDownUtil.GetValidFileName(p.ownerName, filterSlash: true).Trim().TrimEnd('.').Trim(),
"ownerMid" => p.ownerMid ?? "",
_ => $"<{key}>"
};
value = value.Replace(m.Value, v);
}
return value;
}
}
}
5 changes: 4 additions & 1 deletion BBDown/CommandLineInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ internal class CommandLineInvoker
private readonly static Option<string> UposHost = new(new string[] { "--upos-host" }, "自定义upos服务器");
private readonly static Option<bool> ForceReplaceHost = new(new string[] { "--force-replace-host" }, "强制替换下载服务器host(默认开启)");
private readonly static Option<bool> SaveArchivesToFile = new(new string[] { "--save-archives-to-file" }, "将下载过的视频记录到本地文件中, 用于后续跳过下载同个视频");
private readonly static Option<string> FfmpegMetadata = new(new string[] { "--ffmpeg-metadata","-fdata" }, "自定义ffmepg当中的metadata数据: (-fdata artist=\"作者\",title=\"标题\",album=\"专辑\",description=\"简介\")");
private readonly static Option<string> DelayPerPage = new(new string[] { "--delay-per-page" }, "设置下载合集分P之间的下载间隔时间(单位: 秒, 默认无间隔)");
private readonly static Option<string> FilePattern = new(new string[] { "--file-pattern", "-F" },
$"使用内置变量自定义单P存储文件名:\r\n\r\n" +
Expand Down Expand Up @@ -154,6 +155,7 @@ protected override MyOption GetBoundValue(BindingContext bindingContext)
if (bindingContext.ParseResult.HasOption(AddDfnSubfix)) option.AddDfnSubfix = bindingContext.ParseResult.GetValueForOption(AddDfnSubfix)!;
if (bindingContext.ParseResult.HasOption(NoPaddingPageNum)) option.NoPaddingPageNum = bindingContext.ParseResult.GetValueForOption(NoPaddingPageNum)!;
if (bindingContext.ParseResult.HasOption(BandwithAscending)) option.BandwithAscending = bindingContext.ParseResult.GetValueForOption(BandwithAscending)!;
if (bindingContext.ParseResult.HasOption(FfmpegMetadata)) option.FfmpegMetadata = bindingContext.ParseResult.GetValueForOption(FfmpegMetadata)!;
return option;
}
}
Expand Down Expand Up @@ -216,7 +218,8 @@ public static RootCommand GetRootCommand(Func<MyOption, Task> action)
OnlyAv1,
AddDfnSubfix,
NoPaddingPageNum,
BandwithAscending
BandwithAscending,
FfmpegMetadata
};

rootCommand.SetHandler(async (myOption) => await action(myOption), new MyOptionBinder());
Expand Down
1 change: 1 addition & 0 deletions BBDown/MyOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ internal class MyOption
public string Mp4boxPath { get; set; } = "";
public string Aria2cPath { get; set; } = "";
public string UposHost { get; set; } = "";
public string FfmpegMetadata { get; set; } = "";
public string DelayPerPage { get; set; } = "0";
public string Host { get; set; } = "api.bilibili.com";
public string EpHost { get; set; } = "api.bilibili.com";
Expand Down
8 changes: 5 additions & 3 deletions BBDown/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,8 @@ private static async Task DownloadPageAsync(Page p, MyOption myOption, VInfo vIn
(pagesCount > 1 || (bangumi && !vInfo.IsBangumiEnd)) ? p.title : "",
File.Exists(coverPath) ? coverPath : "",
lang,
subtitleInfo, myOption.AudioOnly, myOption.VideoOnly, p.points, p.pubTime, myOption.SimplyMux);
subtitleInfo, myOption.AudioOnly, myOption.VideoOnly, p.points,
p.pubTime, myOption.SimplyMux, myOption, p, pagesCount);
if (code != 0 || !File.Exists(savePath) || new FileInfo(savePath).Length == 0)
{
LogError("合并失败"); return;
Expand Down Expand Up @@ -715,7 +716,8 @@ private static async Task DownloadPageAsync(Page p, MyOption myOption, VInfo vIn
(pagesCount > 1 || (bangumi && !vInfo.IsBangumiEnd)) ? p.title : "",
File.Exists(coverPath) ? coverPath : "",
lang,
subtitleInfo, myOption.AudioOnly, myOption.VideoOnly, p.points, p.pubTime, myOption.SimplyMux);
subtitleInfo, myOption.AudioOnly, myOption.VideoOnly, p.points, p.pubTime,
myOption.SimplyMux, myOption, p, pagesCount);
if (code != 0 || !File.Exists(savePath) || new FileInfo(savePath).Length == 0)
{
LogError("合并失败"); return;
Expand Down Expand Up @@ -843,6 +845,6 @@ private static string FormatSavePath(string savePathFormat, string title, Video?
}

[GeneratedRegex("<([\\w:]+?)>")]
private static partial Regex InfoRegex();
public static partial Regex InfoRegex();
}
}