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

添加新命令,可以将音频封装导出为flac #523

Open
wants to merge 6 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
2 changes: 1 addition & 1 deletion BBDown.Core/Fetcher/NormalInfoFetcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public async Task<VInfo> FetchAsync(string id)
string ownerMid = owner.GetProperty("mid").ToString();
string ownerName = owner.GetProperty("name").ToString();
string pubTime = data.GetProperty("pubdate").ToString();
pubTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(pubTime)).ToLocalTime().ToString();
pubTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Convert.ToDouble(pubTime)).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
bool bangumi = false;

var pages = data.GetProperty("pages").EnumerateArray().ToList();
Expand Down
14 changes: 9 additions & 5 deletions BBDown/BBDownMuxer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public static int MuxByMp4box(string videoPath, string audioPath, string outPath
return RunExe(MP4BOX, arguments, MP4BOX != "mp4box");
}

public static int MuxAV(bool useMp4box, string videoPath, string audioPath, 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)
public static int MuxAV(bool useMp4box, string videoPath, string audioPath, string outPath, string desc = "", string title = "", string author = "", string episodeId = "", string pic = "", string lang = "", List<Subtitle>? subs = null, bool audioOnly = false, bool videoOnly = false, bool useFlac = false, List<ViewPoint>? points = null)
{
if (audioOnly && audioPath != "")
videoPath = "";
Expand Down Expand Up @@ -155,10 +155,14 @@ public static int MuxAV(bool useMp4box, string videoPath, string audioPath, stri
$"-metadata description=\"{desc}\" " +
$"-metadata artist=\"{author}\" " +
(episodeId == "" ? "" : $"-metadata album=\"{title}\" ") +
$"-c copy " + (audioOnly && audioPath == "" ? " -vn " : "") +
(subs != null ? " -c:s mov_text " : "") +
"-movflags faststart -strict unofficial -strict -2 -f mp4 " +
$"\"{outPath}\"";
$"-c copy ";
if (!(audioOnly && useFlac))
{
arguments += (audioOnly && audioPath == "" ? " -vn " : "") +
(subs != null ? " -c:s mov_text " : "") +
"-movflags faststart -strict unofficial -strict -2 -f mp4 ";
}
arguments += $"\"{outPath}\"";
LogDebug("ffmpeg命令:{0}", arguments);
return RunExe(FFMPEG, arguments, FFMPEG != "ffmpeg");
}
Expand Down
10 changes: 5 additions & 5 deletions BBDown/CommandLineInvoker.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System;
using System.CommandLine;
using System.CommandLine.Binding;
using System.CommandLine.Parsing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BBDown
Expand All @@ -16,6 +13,7 @@ internal class CommandLineInvoker
private readonly static Option<bool> UseAppApi = new(new string[] { "--use-app-api", "-app" }, "使用APP端解析模式");
private readonly static Option<bool> UseIntlApi = new(new string[] { "--use-intl-api", "-intl" }, "使用国际版(东南亚视频)解析模式");
private readonly static Option<bool> UseMP4box = new(new string[] { "--use-mp4box" }, "使用MP4Box来混流");
private readonly static Option<bool> UseFlac = new(new string[] { "--use-flac" }, "仅下载音频时可用于指定音频使用Flac封装");
private readonly static Option<string> EncodingPriority = new(new string[] { "--encoding-priority" }, "视频编码的选择优先级, 用逗号分割 例: \"hevc,av1,avc\"");
private readonly static Option<string> DfnPriority = new(new string[] { "--dfn-priority" }, "画质优先级,用逗号分隔 例: \"8K 超高清, 1080P 高码率, HDR 真彩, 杜比视界\"");
private readonly static Option<bool> OnlyShowInfo = new(new string[] { "--only-show-info", "-info" }, "仅解析而不进行下载");
Expand Down Expand Up @@ -46,7 +44,7 @@ internal class CommandLineInvoker
private readonly static Option<string> Aria2cPath = new(new string[] { "--aria2c-path" }, "设置aria2c的路径");
private readonly static Option<string> UposHost = new(new string[] { "--upos-host" }, "自定义upos服务器");
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" + $"<videoTitle>: 视频主标题\r\n" + $"<pageNumber>: 视频分P序号\r\n" + $"<pageNumberWithZero>: 视频分P序号(前缀补零)\r\n" + $"<pageTitle>: 视频分P标题\r\n" + $"<aid>: 视频aid\r\n" + $"<cid>: 视频cid\r\n" + $"<dfn>: 视频清晰度\r\n" + $"<res>: 视频分辨率\r\n" + $"<fps>: 视频帧率\r\n" + $"<videoCodecs>: 视频编码\r\n" + $"<videoBandwidth>: 视频码率\r\n" + $"<audioCodecs>: 音频编码\r\n" + $"<audioBandwidth>: 音频码率\r\n" + $"<ownerName>: 上传者名称\r\n" + $"<ownerMid>: 上传者mid\r\n\r\n" + $"默认为: {Program.SinglePageDefaultSavePath}\r\n");
private readonly static Option<string> FilePattern = new(new string[] { "--file-pattern", "-F" }, $"使用内置变量自定义单P存储文件名:\r\n\r\n" + $"<videoTitle>: 视频主标题\r\n" + $"<pageNumber>: 视频分P序号\r\n" + $"<pageNumberWithZero>: 视频分P序号(前缀补零)\r\n" + $"<pageTitle>: 视频分P标题\r\n" + $"<aid>: 视频aid\r\n" + $"<cid>: 视频cid\r\n" + $"<dfn>: 视频清晰度\r\n" + $"<res>: 视频分辨率\r\n" + $"<fps>: 视频帧率\r\n" + $"<videoCodecs>: 视频编码\r\n" + $"<videoBandwidth>: 视频码率\r\n" + $"<audioCodecs>: 音频编码\r\n" + $"<audioBandwidth>: 音频码率\r\n" + $"<ownerName>: 上传者名称\r\n" + $"<ownerMid>: 上传者mid\r\n" + $"<publishTime>: 上传时间\r\n\r\n" + $"默认为: {Program.SinglePageDefaultSavePath}\r\n");
private readonly static Option<string> MultiFilePattern = new(new string[] { "--multi-file-pattern", "-M" }, $"使用内置变量自定义多P存储文件名:\r\n\r\n" + $"默认为: {Program.MultiPageDefaultSavePath}\r\n");
private readonly static Option<string> Host = new(new string[] { "--host" }, "指定BiliPlus host(使用BiliPlus需要access_token, 不需要cookie, 解析服务器能够获取你账号的大部分权限!)");
private readonly static Option<string> EpHost = new(new string[] { "--ep-host" }, "指定BiliPlus EP host(用于代理api.bilibili.com/pgc/view/web/season, 大部分解析服务器不支持代理该接口)");
Expand All @@ -73,6 +71,7 @@ protected override MyOption GetBoundValue(BindingContext bindingContext)
if (bindingContext.ParseResult.HasOption(UseAppApi)) option.UseAppApi = bindingContext.ParseResult.GetValueForOption(UseAppApi)!;
if (bindingContext.ParseResult.HasOption(UseIntlApi)) option.UseIntlApi = bindingContext.ParseResult.GetValueForOption(UseIntlApi)!;
if (bindingContext.ParseResult.HasOption(UseMP4box)) option.UseMP4box = bindingContext.ParseResult.GetValueForOption(UseMP4box)!;
if (bindingContext.ParseResult.HasOption(UseFlac)) option.UseFlac = bindingContext.ParseResult.GetValueForOption(UseFlac)!;
if (bindingContext.ParseResult.HasOption(EncodingPriority)) option.EncodingPriority = bindingContext.ParseResult.GetValueForOption(EncodingPriority)!;
if (bindingContext.ParseResult.HasOption(DfnPriority)) option.DfnPriority = bindingContext.ParseResult.GetValueForOption(DfnPriority)!;
if (bindingContext.ParseResult.HasOption(OnlyShowInfo)) option.OnlyShowInfo = bindingContext.ParseResult.GetValueForOption(OnlyShowInfo)!;
Expand Down Expand Up @@ -128,6 +127,7 @@ public static RootCommand GetRootCommand(Func<MyOption, Task> action)
UseAppApi,
UseIntlApi,
UseMP4box,
UseFlac,
EncodingPriority,
DfnPriority,
OnlyShowInfo,
Expand Down
1 change: 1 addition & 0 deletions BBDown/MyOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal class MyOption
public bool UseAppApi { get; set; }
public bool UseIntlApi { get; set; }
public bool UseMP4box { get; set; }
public bool UseFlac { get; set; }
public string? EncodingPriority { get; set; }
public string? DfnPriority { get; set; }
public bool OnlyShowInfo { get; set; }
Expand Down
17 changes: 9 additions & 8 deletions BBDown/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
using BBDown.Core.Util;
using BBDown.Core.Fetcher;
using System.Text.Json.Serialization;
using System.CommandLine.Binding;

namespace BBDown
{
Expand Down Expand Up @@ -180,6 +179,7 @@ private static async Task DoWorkAsync(MyOption myOption)
}
}

bool useFlac = myOption.UseFlac;
bool hideStreams = myOption.HideStreams;
bool multiThread = myOption.MultiThread;
bool audioOnly = myOption.AudioOnly;
Expand Down Expand Up @@ -512,7 +512,7 @@ private static async Task DoWorkAsync(MyOption myOption)
await SubUtil.SaveSubtitleAsync(s.url, s.path);
if (subOnly && File.Exists(s.path) && File.ReadAllText(s.path) != "")
{
var _outSubPath = FormatSavePath(savePathFormat, title, null, null, p, pagesCount);
var _outSubPath = FormatSavePath(savePathFormat, title, null, null, p, pagesCount, pubTime);
if (_outSubPath.Contains('/'))
{
if (!Directory.Exists(_outSubPath.Split('/').First()))
Expand Down Expand Up @@ -657,7 +657,7 @@ private static async Task DoWorkAsync(MyOption myOption)
}

LogDebug("Format Before: " + savePathFormat);
savePath = FormatSavePath(savePathFormat, title, videoTracks.ElementAtOrDefault(vIndex), audioTracks.ElementAtOrDefault(aIndex), p, pagesCount);
savePath = FormatSavePath(savePathFormat, title, videoTracks.ElementAtOrDefault(vIndex), audioTracks.ElementAtOrDefault(aIndex), p, pagesCount, pubTime);
LogDebug("Format After: " + savePath);

if (downloadDanmaku)
Expand Down Expand Up @@ -753,15 +753,15 @@ private static async Task DoWorkAsync(MyOption myOption)
if (skipMux) continue;
Log("开始合并音视频" + (subtitleInfo.Count > 0 ? "和字幕" : "") + "...");
if (audioOnly)
savePath = string.Join("", savePath.Take(savePath.Length - 4)) + ".m4a";
savePath = string.Join("", savePath.Take(savePath.Length - 4)) + (useFlac && audioTracks[aIndex].codecs.Equals("FLAC") ? ".flac" : ".m4a");
int code = MuxAV(useMp4box, videoPath, audioPath, savePath,
desc,
title,
p.ownerName ?? "",
(pagesCount > 1 || (bangumi && !vInfo.IsBangumiEnd)) ? p.title : "",
File.Exists(coverPath) ? coverPath : "",
lang,
subtitleInfo, audioOnly, videoOnly, p.points);
subtitleInfo, audioOnly, videoOnly, (useFlac && audioTracks[aIndex].codecs.Equals("FLAC")), p.points);
if (code != 0 || !File.Exists(savePath) || new FileInfo(savePath).Length == 0)
{
LogError("合并失败"); continue;
Expand Down Expand Up @@ -812,7 +812,7 @@ private static async Task DoWorkAsync(MyOption myOption)
}
}
if (infoMode) continue;
savePath = FormatSavePath(savePathFormat, title, videoTracks.ElementAtOrDefault(vIndex), null, p, pagesCount);
savePath = FormatSavePath(savePathFormat, title, videoTracks.ElementAtOrDefault(vIndex), null, p, pagesCount, pubTime);
if (File.Exists(savePath) && new FileInfo(savePath).Length != 0)
{
Log($"{savePath}已存在, 跳过下载...");
Expand Down Expand Up @@ -871,7 +871,7 @@ private static async Task DoWorkAsync(MyOption myOption)
(pagesCount > 1 || (bangumi && !vInfo.IsBangumiEnd)) ? p.title : "",
File.Exists(coverPath) ? coverPath : "",
lang,
subtitleInfo, audioOnly, videoOnly, p.points);
subtitleInfo, audioOnly, videoOnly, useFlac, p.points);
if (code != 0 || !File.Exists(savePath) || new FileInfo(savePath).Length == 0)
{
LogError("合并失败"); continue;
Expand Down Expand Up @@ -948,7 +948,7 @@ private static List<Video> SortTracks(List<Video> videoTracks, Dictionary<string
.ToList();
}

private static string FormatSavePath(string savePathFormat, string title, Video? videoTrack, Audio? audioTrack, Page p, int pagesCount)
private static string FormatSavePath(string savePathFormat, string title, Video? videoTrack, Audio? audioTrack, Page p, int pagesCount, string pubTime)
{
var result = savePathFormat.Replace('\\', '/');
var regex = InfoRegex();
Expand All @@ -972,6 +972,7 @@ private static string FormatSavePath(string savePathFormat, string title, Video?
"videoBandwidth" => videoTrack == null ? "" : videoTrack.bandwith.ToString(),
"audioCodecs" => audioTrack == null ? "" : audioTrack.codecs,
"audioBandwidth" => audioTrack == null ? "" : audioTrack.bandwith.ToString(),
"publishTime" => pubTime,
_ => key
};
result = result.Replace(m.Value, v);
Expand Down