支持 ffmpeg concat 分离器 #254

This commit is contained in:
nilaoda 2023-08-20 22:48:12 +08:00
parent 10e67aa14b
commit 836a90800b
6 changed files with 33 additions and 7 deletions

View File

@ -28,6 +28,7 @@ namespace N_m3u8DL_RE.Common.Resource
public static string cmd_appendUrlParams { get => GetText("cmd_appendUrlParams"); }
public static string cmd_autoSelect { get => GetText("cmd_autoSelect"); }
public static string cmd_binaryMerge { get => GetText("cmd_binaryMerge"); }
public static string cmd_useFFmpegConcatDemuxer { get => GetText("cmd_useFFmpegConcatDemuxer"); }
public static string cmd_checkSegmentsCount { get => GetText("cmd_checkSegmentsCount"); }
public static string cmd_decryptionBinaryPath { get => GetText("cmd_decryptionBinaryPath"); }
public static string cmd_delAfterDone { get => GetText("cmd_delAfterDone"); }

View File

@ -172,6 +172,12 @@ namespace N_m3u8DL_RE.Common.Resource
zhTW: "二進位制合併",
enUS: "Binary merge"
),
["cmd_useFFmpegConcatDemuxer"] = new TextContainer
(
zhCN: "使用 ffmpeg 合并时,使用 concat 分离器而非 concat 协议",
zhTW: "使用 ffmpeg 合併時,使用 concat 分離器而非 concat 協議",
enUS: "When merging with ffmpeg, use the concat demuxer instead of the concat protocol"
),
["cmd_checkSegmentsCount"] = new TextContainer
(
zhCN: "检测实际下载的分片数量和预期数量是否匹配",

View File

@ -18,7 +18,7 @@ namespace N_m3u8DL_RE.CommandLine
{
internal partial class CommandInvoker
{
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20230730";
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20230820";
[GeneratedRegex("((best|worst)\\d*|all)")]
private static partial Regex ForStrRegex();
@ -45,6 +45,7 @@ namespace N_m3u8DL_RE.CommandLine
private readonly static Option<bool> SkipDownload = new(new string[] { "--skip-download" }, description: ResString.cmd_skipDownload, getDefaultValue: () => false);
private readonly static Option<bool> NoDateInfo = new(new string[] { "--no-date-info" }, description: ResString.cmd_noDateInfo, getDefaultValue: () => false);
private readonly static Option<bool> BinaryMerge = new(new string[] { "--binary-merge" }, description: ResString.cmd_binaryMerge, getDefaultValue: () => false);
private readonly static Option<bool> UseFFmpegConcatDemuxer = new(new string[] { "--use-ffmpeg-concat-demuxer" }, description: ResString.cmd_useFFmpegConcatDemuxer, getDefaultValue: () => false);
private readonly static Option<bool> DelAfterDone = new(new string[] { "--del-after-done" }, description: ResString.cmd_delAfterDone, getDefaultValue: () => true);
private readonly static Option<bool> AutoSubtitleFix = new(new string[] { "--auto-subtitle-fix" }, description: ResString.cmd_subtitleFix, getDefaultValue: () => true);
private readonly static Option<bool> CheckSegmentsCount = new(new string[] { "--check-segments-count" }, description: ResString.cmd_checkSegmentsCount, getDefaultValue: () => true);
@ -483,6 +484,7 @@ namespace N_m3u8DL_RE.CommandLine
AutoSelect = bindingContext.ParseResult.GetValueForOption(AutoSelect),
SkipMerge = bindingContext.ParseResult.GetValueForOption(SkipMerge),
BinaryMerge = bindingContext.ParseResult.GetValueForOption(BinaryMerge),
UseFFmpegConcatDemuxer = bindingContext.ParseResult.GetValueForOption(UseFFmpegConcatDemuxer),
DelAfterDone = bindingContext.ParseResult.GetValueForOption(DelAfterDone),
AutoSubtitleFix = bindingContext.ParseResult.GetValueForOption(AutoSubtitleFix),
CheckSegmentsCount = bindingContext.ParseResult.GetValueForOption(CheckSegmentsCount),
@ -589,7 +591,7 @@ namespace N_m3u8DL_RE.CommandLine
var rootCommand = new RootCommand(VERSION_INFO)
{
Input, TmpDir, SaveDir, SaveName, BaseUrl, ThreadCount, DownloadRetryCount, AutoSelect, SkipMerge, SkipDownload, CheckSegmentsCount,
BinaryMerge, DelAfterDone, NoDateInfo, NoLog, WriteMetaJson, AppendUrlParams, ConcurrentDownload, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
BinaryMerge, UseFFmpegConcatDemuxer, DelAfterDone, NoDateInfo, NoLog, WriteMetaJson, AppendUrlParams, ConcurrentDownload, Headers, /**SavePattern,**/ SubOnly, SubtitleFormat, AutoSubtitleFix,
FFmpegBinaryPath,
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption,
MaxSpeed,

View File

@ -85,6 +85,10 @@ namespace N_m3u8DL_RE.CommandLine
/// </summary>
public bool BinaryMerge { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.UseFFmpegConcatDemuxer"/>.
/// </summary>
public bool UseFFmpegConcatDemuxer { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.DelAfterDone"/>.
/// </summary>
public bool DelAfterDone { get; set; }

View File

@ -557,7 +557,7 @@ namespace N_m3u8DL_RE.DownloadManager
};
}
}
mergeSuccess = MergeUtil.MergeByFFmpeg(DownloaderConfig.MyOptions.FFmpegBinaryPath!, files, Path.ChangeExtension(ffOut, null), ext, useAACFilter, writeDate: !DownloaderConfig.MyOptions.NoDateInfo);
mergeSuccess = MergeUtil.MergeByFFmpeg(DownloaderConfig.MyOptions.FFmpegBinaryPath!, files, Path.ChangeExtension(ffOut, null), ext, useAACFilter, writeDate: !DownloaderConfig.MyOptions.NoDateInfo, useConcatDemuxer: DownloaderConfig.MyOptions.UseFFmpegConcatDemuxer);
if (mergeSuccess) output = ffOut;
}
}

View File

@ -110,7 +110,7 @@ namespace N_m3u8DL_RE.Util
public static bool MergeByFFmpeg(string binary, string[] files, string outputPath, string muxFormat, bool useAACFilter,
bool fastStart = false,
bool writeDate = true, string poster = "", string audioName = "", string title = "",
bool writeDate = true, bool useConcatDemuxer = false, string poster = "", string audioName = "", string title = "",
string copyright = "", string comment = "", string encodingTool = "", string recTime = "")
{
//改为绝对路径
@ -118,16 +118,29 @@ namespace N_m3u8DL_RE.Util
string dateString = string.IsNullOrEmpty(recTime) ? DateTime.Now.ToString("o") : recTime;
StringBuilder command = new StringBuilder("-loglevel warning -nostdin -i concat:\"");
StringBuilder command = new StringBuilder("-loglevel warning -nostdin ");
string ddpAudio = string.Empty;
string addPoster = "-map 1 -c:v:1 copy -disposition:v:1 attached_pic";
ddpAudio = (File.Exists($"{Path.GetFileNameWithoutExtension(outputPath + ".mp4")}.txt") ? File.ReadAllText($"{Path.GetFileNameWithoutExtension(outputPath + ".mp4")}.txt") : "");
if (!string.IsNullOrEmpty(ddpAudio)) useAACFilter = false;
foreach (string t in files)
if (useConcatDemuxer)
{
command.Append(Path.GetFileName(t) + "|");
// 使用 concat demuxer合并
var text = string.Join(Environment.NewLine, files.Select(f => $"file '{f}'"));
var tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, text);
command.Append($" -f concat -safe 0 -i \"{tempFile}");
}
else
{
command.Append(" -i concat:\"");
foreach (string t in files)
{
command.Append(Path.GetFileName(t) + "|");
}
}
switch (muxFormat.ToUpper())
{