支持TS格式混流 (#466)

This commit is contained in:
nilaoda 2024-10-20 21:41:55 +08:00 committed by GitHub
parent 2bf4f29f28
commit 164f2cb59b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 43 additions and 38 deletions

View File

@ -18,7 +18,7 @@ namespace N_m3u8DL_RE.CommandLine
{ {
internal partial class CommandInvoker internal partial class CommandInvoker
{ {
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20240630"; public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20241020";
[GeneratedRegex("((best|worst)\\d*|all)")] [GeneratedRegex("((best|worst)\\d*|all)")]
private static partial Regex ForStrRegex(); private static partial Regex ForStrRegex();
@ -438,7 +438,8 @@ namespace N_m3u8DL_RE.CommandLine
var p = new ComplexParamParser(v); var p = new ComplexParamParser(v);
//混流格式 //混流格式
var format = p.GetValue("format") ?? v.Split(':')[0]; //若未获取到,直接:前的字符串作为format解析 var format = p.GetValue("format") ?? v.Split(':')[0]; //若未获取到,直接:前的字符串作为format解析
if (format != "mp4" && format != "mkv") var parseResult = System.Enum.TryParse(format.ToUpperInvariant(), out MuxFormat muxFormat);
if (!parseResult)
{ {
result.ErrorMessage = $"format={format} not valid"; result.ErrorMessage = $"format={format} not valid";
return null; return null;
@ -480,7 +481,7 @@ namespace N_m3u8DL_RE.CommandLine
return new MuxOptions() return new MuxOptions()
{ {
UseMkvmerge = muxer == "mkvmerge", UseMkvmerge = muxer == "mkvmerge",
MuxToMp4 = format == "mp4", MuxFormat = muxFormat,
KeepFiles = keep == "true", KeepFiles = keep == "true",
SkipSubtitle = skipSub == "true", SkipSubtitle = skipSub == "true",
BinPath = bin_path == "auto" ? null : bin_path BinPath = bin_path == "auto" ? null : bin_path

View File

@ -725,14 +725,14 @@ namespace N_m3u8DL_RE.DownloadManager
} }
OutputFiles.ForEach(f => Logger.WarnMarkUp($"[grey]{Path.GetFileName(f.FilePath).EscapeMarkup()}[/]")); OutputFiles.ForEach(f => Logger.WarnMarkUp($"[grey]{Path.GetFileName(f.FilePath).EscapeMarkup()}[/]"));
var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory; var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory;
var ext = DownloaderConfig.MyOptions.MuxOptions.MuxToMp4 ? ".mp4" : ".mkv"; var ext = OtherUtil.GetMuxExtension(DownloaderConfig.MyOptions.MuxOptions.MuxFormat);
var dirName = Path.GetFileName(DownloaderConfig.DirPrefix); var dirName = Path.GetFileName(DownloaderConfig.DirPrefix);
var outName = $"{dirName}.MUX"; var outName = $"{dirName}.MUX";
var outPath = Path.Combine(saveDir, outName); var outPath = Path.Combine(saveDir, outName);
Logger.WarnMarkUp($"Muxing to [grey]{outName.EscapeMarkup()}{ext}[/]"); Logger.WarnMarkUp($"Muxing to [grey]{outName.EscapeMarkup()}{ext}[/]");
var result = false; var result = false;
if (DownloaderConfig.MyOptions.MuxOptions.UseMkvmerge) result = MergeUtil.MuxInputsByMkvmerge(DownloaderConfig.MyOptions.MkvmergeBinaryPath!, OutputFiles.ToArray(), outPath); if (DownloaderConfig.MyOptions.MuxOptions.UseMkvmerge) result = MergeUtil.MuxInputsByMkvmerge(DownloaderConfig.MyOptions.MkvmergeBinaryPath!, OutputFiles.ToArray(), outPath);
else result = MergeUtil.MuxInputsByFFmpeg(DownloaderConfig.MyOptions.FFmpegBinaryPath!, OutputFiles.ToArray(), outPath, DownloaderConfig.MyOptions.MuxOptions.MuxToMp4, !DownloaderConfig.MyOptions.NoDateInfo); else result = MergeUtil.MuxInputsByFFmpeg(DownloaderConfig.MyOptions.FFmpegBinaryPath!, OutputFiles.ToArray(), outPath, DownloaderConfig.MyOptions.MuxOptions.MuxFormat, !DownloaderConfig.MyOptions.NoDateInfo);
//完成后删除各轨道文件 //完成后删除各轨道文件
if (result) if (result)
{ {

View File

@ -896,14 +896,14 @@ namespace N_m3u8DL_RE.DownloadManager
} }
OutputFiles.ForEach(f => Logger.WarnMarkUp($"[grey]{Path.GetFileName(f.FilePath).EscapeMarkup()}[/]")); OutputFiles.ForEach(f => Logger.WarnMarkUp($"[grey]{Path.GetFileName(f.FilePath).EscapeMarkup()}[/]"));
var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory; var saveDir = DownloaderConfig.MyOptions.SaveDir ?? Environment.CurrentDirectory;
var ext = DownloaderConfig.MyOptions.MuxOptions.MuxToMp4 ? ".mp4" : ".mkv"; var ext = OtherUtil.GetMuxExtension(DownloaderConfig.MyOptions.MuxOptions.MuxFormat);
var dirName = Path.GetFileName(DownloaderConfig.DirPrefix); var dirName = Path.GetFileName(DownloaderConfig.DirPrefix);
var outName = $"{dirName}.MUX"; var outName = $"{dirName}.MUX";
var outPath = Path.Combine(saveDir, outName); var outPath = Path.Combine(saveDir, outName);
Logger.WarnMarkUp($"Muxing to [grey]{outName.EscapeMarkup()}{ext}[/]"); Logger.WarnMarkUp($"Muxing to [grey]{outName.EscapeMarkup()}{ext}[/]");
var result = false; var result = false;
if (DownloaderConfig.MyOptions.MuxOptions.UseMkvmerge) result = MergeUtil.MuxInputsByMkvmerge(DownloaderConfig.MyOptions.MkvmergeBinaryPath!, OutputFiles.ToArray(), outPath); if (DownloaderConfig.MyOptions.MuxOptions.UseMkvmerge) result = MergeUtil.MuxInputsByMkvmerge(DownloaderConfig.MyOptions.MkvmergeBinaryPath!, OutputFiles.ToArray(), outPath);
else result = MergeUtil.MuxInputsByFFmpeg(DownloaderConfig.MyOptions.FFmpegBinaryPath!, OutputFiles.ToArray(), outPath, DownloaderConfig.MyOptions.MuxOptions.MuxToMp4, !DownloaderConfig.MyOptions.NoDateInfo); else result = MergeUtil.MuxInputsByFFmpeg(DownloaderConfig.MyOptions.FFmpegBinaryPath!, OutputFiles.ToArray(), outPath, DownloaderConfig.MyOptions.MuxOptions.MuxFormat, !DownloaderConfig.MyOptions.NoDateInfo);
//完成后删除各轨道文件 //完成后删除各轨道文件
if (result) if (result)
{ {

View File

@ -1,15 +1,11 @@
using System; using N_m3u8DL_RE.Enum;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace N_m3u8DL_RE.Entity namespace N_m3u8DL_RE.Entity
{ {
internal class MuxOptions internal class MuxOptions
{ {
public bool UseMkvmerge { get; set; } = false; public bool UseMkvmerge { get; set; } = false;
public bool MuxToMp4 { get; set; } = false; public MuxFormat MuxFormat { get; set; } = MuxFormat.MP4;
public bool KeepFiles { get; set; } = false; public bool KeepFiles { get; set; } = false;
public bool SkipSubtitle { get; set; } = false; public bool SkipSubtitle { get; set; } = false;
public string? BinPath { get; set; } public string? BinPath { get; set; }

View File

@ -0,0 +1,8 @@
namespace N_m3u8DL_RE.Enum;
internal enum MuxFormat
{
MP4,
MKV,
TS,
}

View File

@ -1,14 +1,7 @@
using System; namespace N_m3u8DL_RE.Enum;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace N_m3u8DL_RE.Enum internal enum SubtitleFormat
{ {
internal enum SubtitleFormat VTT,
{ SRT
VTT, }
SRT
}
}

View File

@ -1,16 +1,9 @@
using N_m3u8DL_RE.Common.Log; using N_m3u8DL_RE.Common.Log;
using N_m3u8DL_RE.Entity; using N_m3u8DL_RE.Entity;
using Spectre.Console; using Spectre.Console;
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using N_m3u8DL_RE.Enum;
using System.Xml;
using System.Xml.Linq;
namespace N_m3u8DL_RE.Util namespace N_m3u8DL_RE.Util
{ {
@ -186,9 +179,9 @@ namespace N_m3u8DL_RE.Util
return code == 0; return code == 0;
} }
public static bool MuxInputsByFFmpeg(string binary, OutputFile[] files, string outputPath, bool mp4, bool dateinfo) public static bool MuxInputsByFFmpeg(string binary, OutputFile[] files, string outputPath, MuxFormat muxFormat, bool dateinfo)
{ {
var ext = mp4 ? "mp4" : "mkv"; var ext = OtherUtil.GetMuxExtension(muxFormat);
string dateString = DateTime.Now.ToString("o"); string dateString = DateTime.Now.ToString("o");
StringBuilder command = new StringBuilder("-loglevel warning -nostdin -y -dn "); StringBuilder command = new StringBuilder("-loglevel warning -nostdin -y -dn ");
@ -206,10 +199,13 @@ namespace N_m3u8DL_RE.Util
var srt = files.Any(x => x.FilePath.EndsWith(".srt")); var srt = files.Any(x => x.FilePath.EndsWith(".srt"));
if (mp4) if (muxFormat == MuxFormat.MP4)
command.Append($" -strict unofficial -c:a copy -c:v copy -c:s mov_text "); //mp4不支持vtt/srt字幕必须转换格式 command.Append($" -strict unofficial -c:a copy -c:v copy -c:s mov_text "); //mp4不支持vtt/srt字幕必须转换格式
else else if (muxFormat == MuxFormat.TS)
command.Append($" -strict unofficial -c:a copy -c:v copy ");
else if (muxFormat == MuxFormat.MKV)
command.Append($" -strict unofficial -c:a copy -c:v copy -c:s {(srt ? "srt" : "webvtt")} "); command.Append($" -strict unofficial -c:a copy -c:v copy -c:s {(srt ? "srt" : "webvtt")} ");
else throw new ArgumentException($"unknown format: {muxFormat}");
//CLEAN //CLEAN
command.Append(" -map_metadata -1 "); command.Append(" -map_metadata -1 ");
@ -254,7 +250,7 @@ namespace N_m3u8DL_RE.Util
if (dateinfo) command.Append($" -metadata date=\"{dateString}\" "); if (dateinfo) command.Append($" -metadata date=\"{dateString}\" ");
command.Append($" -ignore_unknown -copy_unknown "); command.Append($" -ignore_unknown -copy_unknown ");
command.Append($" \"{outputPath}.{ext}\""); command.Append($" \"{outputPath}{ext}\"");
var code = InvokeFFmpeg(binary, command.ToString(), Environment.CurrentDirectory); var code = InvokeFFmpeg(binary, command.ToString(), Environment.CurrentDirectory);

View File

@ -163,5 +163,16 @@ namespace N_m3u8DL_RE.Util
{ {
return Environment.GetEnvironmentVariable(key) ?? defaultValue; return Environment.GetEnvironmentVariable(key) ?? defaultValue;
} }
public static string GetMuxExtension(MuxFormat muxFormat)
{
return muxFormat switch
{
MuxFormat.MP4 => ".mp4",
MuxFormat.MKV => ".mkv",
MuxFormat.TS => ".ts",
_ => throw new ArgumentException($"unknown format: {muxFormat}")
};
}
} }
} }