新增一系列全新的命令行选项
This commit is contained in:
parent
79b4b68469
commit
aade5a5d7c
|
@ -22,15 +22,18 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resource\ResString.en-US.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resource\ResString.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<PublicClass>true</PublicClass>
|
||||
<LastGenOutput>ResString.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resource\ResString.zh-TW.resx">
|
||||
<EmbeddedResource Update="Resource\ResString.zh-Hans.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<PublicClass>true</PublicClass>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Resource\ResString.zh-Hant.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<PublicClass>true</PublicClass>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 错误的m3u8 的本地化字符串。
|
||||
/// 查找类似 Bad m3u8 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string badM3u8 {
|
||||
get {
|
||||
|
@ -70,7 +70,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 二进制合并中... 的本地化字符串。
|
||||
/// 查找类似 Binary merging... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string binaryMerge {
|
||||
get {
|
||||
|
@ -79,7 +79,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 验证最后一个分片有效性 的本地化字符串。
|
||||
/// 查找类似 Verifying the validity of the last segment 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string checkingLast {
|
||||
get {
|
||||
|
@ -88,7 +88,161 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 获取: 的本地化字符串。
|
||||
/// 查找类似 Automatically selects the best tracks of all types 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_autoSelect {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_autoSelect", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Binary merge 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_binaryMerge {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_binaryMerge", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Check if the actual number of segments downloaded matches the expected number 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_checkSegmentsCount {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_checkSegmentsCount", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Delete temporary files when done 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_delAfterDone {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_delAfterDone", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Pass custom header(s) to server, Example:
|
||||
/// -H "Cookie: mycookie" -H "User-Agent: iOS" 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_header {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_header", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Input Url or File 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_Input {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_Input", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Set log level 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_logLevel {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_logLevel", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Set output directory 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_saveDir {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_saveDir", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Set output filename 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_saveName {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_saveName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Skip download 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_skipDownload {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_skipDownload", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Skip segments merge 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_skipMerge {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_skipMerge", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Subtitle output format 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_subFormat {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_subFormat", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Select only subtitle tracks 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_subOnly {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_subOnly", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Automatically fix subtitles 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_subtitleFix {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_subtitleFix", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Set download thread count 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_threadCount {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_threadCount", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Set temporary file directory 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_tmpDir {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_tmpDir", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Set UI language 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string cmd_uiLanguage {
|
||||
get {
|
||||
return ResourceManager.GetString("cmd_uiLanguage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Fetch: 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string fetch {
|
||||
get {
|
||||
|
@ -97,7 +251,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 正在提取TTML(raw)字幕... 的本地化字符串。
|
||||
/// 查找类似 Extracting TTML(raw) subtitle... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string fixingTTML {
|
||||
get {
|
||||
|
@ -106,7 +260,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 正在提取TTML(mp4)字幕... 的本地化字符串。
|
||||
/// 查找类似 Extracting TTML(mp4) subtitle... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string fixingTTMLmp4 {
|
||||
get {
|
||||
|
@ -115,7 +269,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 正在提取VTT(raw)字幕... 的本地化字符串。
|
||||
/// 查找类似 Extracting VTT(raw) subtitle... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string fixingVTT {
|
||||
get {
|
||||
|
@ -124,7 +278,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 正在提取VTT(mp4)字幕... 的本地化字符串。
|
||||
/// 查找类似 Extracting VTT(mp4) subtitle... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string fixingVTTmp4 {
|
||||
get {
|
||||
|
@ -133,7 +287,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 找不到支持的Processor 的本地化字符串。
|
||||
/// 查找类似 No Processor matched 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string keyProcessorNotFound {
|
||||
get {
|
||||
|
@ -142,7 +296,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 检测到直播流 的本地化字符串。
|
||||
/// 查找类似 Live stream found 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string liveFound {
|
||||
get {
|
||||
|
@ -151,7 +305,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 加载URL: 的本地化字符串。
|
||||
/// 查找类似 Loading URL: 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string loadingUrl {
|
||||
get {
|
||||
|
@ -160,7 +314,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 检测到Master列表,开始解析全部流信息 的本地化字符串。
|
||||
/// 查找类似 Master List detected, try parse all streams 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string masterM3u8Found {
|
||||
get {
|
||||
|
@ -169,7 +323,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 内容匹配: [white on mediumorchid1]Dynamic Adaptive Streaming over HTTP[/] 的本地化字符串。
|
||||
/// 查找类似 Content Matched: [white on mediumorchid1]Dynamic Adaptive Streaming over HTTP[/] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string matchDASH {
|
||||
get {
|
||||
|
@ -178,7 +332,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 内容匹配: [white on deepskyblue1]HTTP Live Streaming[/] 的本地化字符串。
|
||||
/// 查找类似 Content Matched: [white on deepskyblue1]HTTP Live Streaming[/] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string matchHLS {
|
||||
get {
|
||||
|
@ -187,7 +341,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 当前输入不受支持: 的本地化字符串。
|
||||
/// 查找类似 Input not supported: 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string notSupported {
|
||||
get {
|
||||
|
@ -196,7 +350,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 正在解析媒体信息... 的本地化字符串。
|
||||
/// 查找类似 Parsing streams... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string parsingStream {
|
||||
get {
|
||||
|
@ -205,7 +359,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 [grey](按键盘上下键以浏览更多内容)[/] 的本地化字符串。
|
||||
/// 查找类似 [grey](Move up and down to reveal more streams)[/] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string promptChoiceText {
|
||||
get {
|
||||
|
@ -214,7 +368,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 (按 [blue]空格键[/] 选择流, [green]回车键[/] 完成选择) 的本地化字符串。
|
||||
/// 查找类似 (Press [blue]<space>[/] to toggle a stream, [green]<enter>[/] to accept) 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string promptInfo {
|
||||
get {
|
||||
|
@ -223,7 +377,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 请选择 [green]你要下载的内容[/]: 的本地化字符串。
|
||||
/// 查找类似 Please select [green]what you want to download[/]: 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string promptTitle {
|
||||
get {
|
||||
|
@ -232,7 +386,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 分片数量校验不通过, 共{}个,已下载{}. 的本地化字符串。
|
||||
/// 查找类似 Segment count check not pass, total: {}, downloaded: {}. 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string segmentCountCheckNotPass {
|
||||
get {
|
||||
|
@ -241,7 +395,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 已选择的流: 的本地化字符串。
|
||||
/// 查找类似 Selected streams: 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string selectedStream {
|
||||
get {
|
||||
|
@ -250,7 +404,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 开始下载... 的本地化字符串。
|
||||
/// 查找类似 Start downloading... 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string startDownloading {
|
||||
get {
|
||||
|
@ -259,7 +413,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 已解析, 共计 {} 条媒体流, 基本流 {} 条, 可选音频流 {} 条, 可选字幕流 {} 条 的本地化字符串。
|
||||
/// 查找类似 Extracted, there are {} streams, with {} basic streams, {} audio streams, {} subtitle streams 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string streamsInfo {
|
||||
get {
|
||||
|
@ -268,7 +422,7 @@ namespace N_m3u8DL_RE.Common.Resource {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 写出meta.json 的本地化字符串。
|
||||
/// 查找类似 Writing meta.json 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string writeJson {
|
||||
get {
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="badM3u8" xml:space="preserve">
|
||||
<value>Bad m3u8</value>
|
||||
</data>
|
||||
<data name="notSupported" xml:space="preserve">
|
||||
<value>Input not supported: </value>
|
||||
</data>
|
||||
<data name="loadingUrl" xml:space="preserve">
|
||||
<value>Loading URL: </value>
|
||||
</data>
|
||||
<data name="matchHLS" xml:space="preserve">
|
||||
<value>Content Matched: [white on deepskyblue1]HTTP Live Streaming[/]</value>
|
||||
</data>
|
||||
<data name="masterM3u8Found" xml:space="preserve">
|
||||
<value>Master List detected, try parse all streams</value>
|
||||
</data>
|
||||
<data name="fetch" xml:space="preserve">
|
||||
<value>Fetch: </value>
|
||||
</data>
|
||||
<data name="promptTitle" xml:space="preserve">
|
||||
<value>Please select [green]what you want to download[/]:</value>
|
||||
</data>
|
||||
<data name="promptChoiceText" xml:space="preserve">
|
||||
<value>[grey](Move up and down to reveal more streams)[/]</value>
|
||||
</data>
|
||||
<data name="promptInfo" xml:space="preserve">
|
||||
<value>(Press [blue]<space>[/] to toggle a stream, [green]<enter>[/] to accept)</value>
|
||||
</data>
|
||||
<data name="streamsInfo" xml:space="preserve">
|
||||
<value>Extracted, there are {} streams, with {} basic streams, {} audio streams, {} subtitle streams</value>
|
||||
</data>
|
||||
<data name="liveFound" xml:space="preserve">
|
||||
<value>Live stream found</value>
|
||||
</data>
|
||||
<data name="selectedStream" xml:space="preserve">
|
||||
<value>Selected streams:</value>
|
||||
</data>
|
||||
<data name="writeJson" xml:space="preserve">
|
||||
<value>Writing meta.json</value>
|
||||
</data>
|
||||
<data name="matchDASH" xml:space="preserve">
|
||||
<value>Content Matched: [white on mediumorchid1]Dynamic Adaptive Streaming over HTTP[/]</value>
|
||||
</data>
|
||||
<data name="checkingLast" xml:space="preserve">
|
||||
<value>Verifying the validity of the last segment</value>
|
||||
</data>
|
||||
<data name="parsingStream" xml:space="preserve">
|
||||
<value>Parsing streams...</value>
|
||||
</data>
|
||||
<data name="keyProcessorNotFound" xml:space="preserve">
|
||||
<value>No Processor matched</value>
|
||||
</data>
|
||||
<data name="startDownloading" xml:space="preserve">
|
||||
<value>Start downloading...</value>
|
||||
</data>
|
||||
<data name="segmentCountCheckNotPass" xml:space="preserve">
|
||||
<value>Segment count check not pass, total: {}, downloaded: {}.</value>
|
||||
</data>
|
||||
<data name="fixingVTT" xml:space="preserve">
|
||||
<value>Extracting VTT(raw) subtitle...</value>
|
||||
</data>
|
||||
<data name="fixingVTTmp4" xml:space="preserve">
|
||||
<value>Extracting VTT(mp4) subtitle...</value>
|
||||
</data>
|
||||
<data name="binaryMerge" xml:space="preserve">
|
||||
<value>Binary merging...</value>
|
||||
</data>
|
||||
<data name="fixingTTMLmp4" xml:space="preserve">
|
||||
<value>Extracting TTML(mp4) subtitle...</value>
|
||||
</data>
|
||||
<data name="fixingTTML" xml:space="preserve">
|
||||
<value>Extracting TTML(raw) subtitle...</value>
|
||||
</data>
|
||||
</root>
|
|
@ -98,75 +98,127 @@
|
|||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="badM3u8" xml:space="preserve">
|
||||
<value>错误的m3u8</value>
|
||||
<value>Bad m3u8</value>
|
||||
</data>
|
||||
<data name="notSupported" xml:space="preserve">
|
||||
<value>当前输入不受支持: </value>
|
||||
<value>Input not supported: </value>
|
||||
</data>
|
||||
<data name="loadingUrl" xml:space="preserve">
|
||||
<value>加载URL: </value>
|
||||
<value>Loading URL: </value>
|
||||
</data>
|
||||
<data name="matchHLS" xml:space="preserve">
|
||||
<value>内容匹配: [white on deepskyblue1]HTTP Live Streaming[/]</value>
|
||||
<value>Content Matched: [white on deepskyblue1]HTTP Live Streaming[/]</value>
|
||||
</data>
|
||||
<data name="masterM3u8Found" xml:space="preserve">
|
||||
<value>检测到Master列表,开始解析全部流信息</value>
|
||||
<value>Master List detected, try parse all streams</value>
|
||||
</data>
|
||||
<data name="fetch" xml:space="preserve">
|
||||
<value>获取: </value>
|
||||
<value>Fetch: </value>
|
||||
</data>
|
||||
<data name="promptTitle" xml:space="preserve">
|
||||
<value>请选择 [green]你要下载的内容[/]:</value>
|
||||
<value>Please select [green]what you want to download[/]:</value>
|
||||
</data>
|
||||
<data name="promptChoiceText" xml:space="preserve">
|
||||
<value>[grey](按键盘上下键以浏览更多内容)[/]</value>
|
||||
<value>[grey](Move up and down to reveal more streams)[/]</value>
|
||||
</data>
|
||||
<data name="promptInfo" xml:space="preserve">
|
||||
<value>(按 [blue]空格键[/] 选择流, [green]回车键[/] 完成选择)</value>
|
||||
<value>(Press [blue]<space>[/] to toggle a stream, [green]<enter>[/] to accept)</value>
|
||||
</data>
|
||||
<data name="streamsInfo" xml:space="preserve">
|
||||
<value>已解析, 共计 {} 条媒体流, 基本流 {} 条, 可选音频流 {} 条, 可选字幕流 {} 条</value>
|
||||
<value>Extracted, there are {} streams, with {} basic streams, {} audio streams, {} subtitle streams</value>
|
||||
</data>
|
||||
<data name="liveFound" xml:space="preserve">
|
||||
<value>检测到直播流</value>
|
||||
<value>Live stream found</value>
|
||||
</data>
|
||||
<data name="selectedStream" xml:space="preserve">
|
||||
<value>已选择的流:</value>
|
||||
<value>Selected streams:</value>
|
||||
</data>
|
||||
<data name="writeJson" xml:space="preserve">
|
||||
<value>写出meta.json</value>
|
||||
<value>Writing meta.json</value>
|
||||
</data>
|
||||
<data name="matchDASH" xml:space="preserve">
|
||||
<value>内容匹配: [white on mediumorchid1]Dynamic Adaptive Streaming over HTTP[/]</value>
|
||||
<value>Content Matched: [white on mediumorchid1]Dynamic Adaptive Streaming over HTTP[/]</value>
|
||||
</data>
|
||||
<data name="checkingLast" xml:space="preserve">
|
||||
<value>验证最后一个分片有效性</value>
|
||||
<value>Verifying the validity of the last segment</value>
|
||||
</data>
|
||||
<data name="parsingStream" xml:space="preserve">
|
||||
<value>正在解析媒体信息...</value>
|
||||
<value>Parsing streams...</value>
|
||||
</data>
|
||||
<data name="keyProcessorNotFound" xml:space="preserve">
|
||||
<value>找不到支持的Processor</value>
|
||||
<value>No Processor matched</value>
|
||||
</data>
|
||||
<data name="startDownloading" xml:space="preserve">
|
||||
<value>开始下载...</value>
|
||||
<value>Start downloading...</value>
|
||||
</data>
|
||||
<data name="segmentCountCheckNotPass" xml:space="preserve">
|
||||
<value>分片数量校验不通过, 共{}个,已下载{}.</value>
|
||||
<value>Segment count check not pass, total: {}, downloaded: {}.</value>
|
||||
</data>
|
||||
<data name="fixingVTT" xml:space="preserve">
|
||||
<value>正在提取VTT(raw)字幕...</value>
|
||||
<value>Extracting VTT(raw) subtitle...</value>
|
||||
</data>
|
||||
<data name="fixingVTTmp4" xml:space="preserve">
|
||||
<value>正在提取VTT(mp4)字幕...</value>
|
||||
<value>Extracting VTT(mp4) subtitle...</value>
|
||||
</data>
|
||||
<data name="binaryMerge" xml:space="preserve">
|
||||
<value>二进制合并中...</value>
|
||||
<value>Binary merging...</value>
|
||||
</data>
|
||||
<data name="fixingTTMLmp4" xml:space="preserve">
|
||||
<value>正在提取TTML(mp4)字幕...</value>
|
||||
<value>Extracting TTML(mp4) subtitle...</value>
|
||||
</data>
|
||||
<data name="fixingTTML" xml:space="preserve">
|
||||
<value>正在提取TTML(raw)字幕...</value>
|
||||
<value>Extracting TTML(raw) subtitle...</value>
|
||||
</data>
|
||||
<data name="cmd_Input" xml:space="preserve">
|
||||
<value>Input Url or File</value>
|
||||
</data>
|
||||
<data name="cmd_header" xml:space="preserve">
|
||||
<value>Pass custom header(s) to server, Example:
|
||||
-H "Cookie: mycookie" -H "User-Agent: iOS"</value>
|
||||
</data>
|
||||
<data name="cmd_logLevel" xml:space="preserve">
|
||||
<value>Set log level</value>
|
||||
</data>
|
||||
<data name="cmd_autoSelect" xml:space="preserve">
|
||||
<value>Automatically selects the best tracks of all types</value>
|
||||
</data>
|
||||
<data name="cmd_subOnly" xml:space="preserve">
|
||||
<value>Select only subtitle tracks</value>
|
||||
</data>
|
||||
<data name="cmd_threadCount" xml:space="preserve">
|
||||
<value>Set download thread count</value>
|
||||
</data>
|
||||
<data name="cmd_skipMerge" xml:space="preserve">
|
||||
<value>Skip segments merge</value>
|
||||
</data>
|
||||
<data name="cmd_binaryMerge" xml:space="preserve">
|
||||
<value>Binary merge</value>
|
||||
</data>
|
||||
<data name="cmd_delAfterDone" xml:space="preserve">
|
||||
<value>Delete temporary files when done</value>
|
||||
</data>
|
||||
<data name="cmd_subtitleFix" xml:space="preserve">
|
||||
<value>Automatically fix subtitles</value>
|
||||
</data>
|
||||
<data name="cmd_checkSegmentsCount" xml:space="preserve">
|
||||
<value>Check if the actual number of segments downloaded matches the expected number</value>
|
||||
</data>
|
||||
<data name="cmd_subFormat" xml:space="preserve">
|
||||
<value>Subtitle output format</value>
|
||||
</data>
|
||||
<data name="cmd_tmpDir" xml:space="preserve">
|
||||
<value>Set temporary file directory</value>
|
||||
</data>
|
||||
<data name="cmd_saveDir" xml:space="preserve">
|
||||
<value>Set output directory</value>
|
||||
</data>
|
||||
<data name="cmd_saveName" xml:space="preserve">
|
||||
<value>Set output filename</value>
|
||||
</data>
|
||||
<data name="cmd_uiLanguage" xml:space="preserve">
|
||||
<value>Set UI language</value>
|
||||
</data>
|
||||
<data name="cmd_skipDownload" xml:space="preserve">
|
||||
<value>Skip download</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,244 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="badM3u8" xml:space="preserve">
|
||||
<value>错误的m3u8</value>
|
||||
</data>
|
||||
<data name="notSupported" xml:space="preserve">
|
||||
<value>当前输入不受支持: </value>
|
||||
</data>
|
||||
<data name="loadingUrl" xml:space="preserve">
|
||||
<value>加载URL: </value>
|
||||
</data>
|
||||
<data name="matchHLS" xml:space="preserve">
|
||||
<value>内容匹配: [white on deepskyblue1]HTTP Live Streaming[/]</value>
|
||||
</data>
|
||||
<data name="masterM3u8Found" xml:space="preserve">
|
||||
<value>检测到Master列表,开始解析全部流信息</value>
|
||||
</data>
|
||||
<data name="fetch" xml:space="preserve">
|
||||
<value>获取: </value>
|
||||
</data>
|
||||
<data name="promptTitle" xml:space="preserve">
|
||||
<value>请选择 [green]你要下载的内容[/]:</value>
|
||||
</data>
|
||||
<data name="promptChoiceText" xml:space="preserve">
|
||||
<value>[grey](按键盘上下键以浏览更多内容)[/]</value>
|
||||
</data>
|
||||
<data name="promptInfo" xml:space="preserve">
|
||||
<value>(按 [blue]空格键[/] 选择流, [green]回车键[/] 完成选择)</value>
|
||||
</data>
|
||||
<data name="streamsInfo" xml:space="preserve">
|
||||
<value>已解析, 共计 {} 条媒体流, 基本流 {} 条, 可选音频流 {} 条, 可选字幕流 {} 条</value>
|
||||
</data>
|
||||
<data name="liveFound" xml:space="preserve">
|
||||
<value>检测到直播流</value>
|
||||
</data>
|
||||
<data name="selectedStream" xml:space="preserve">
|
||||
<value>已选择的流:</value>
|
||||
</data>
|
||||
<data name="writeJson" xml:space="preserve">
|
||||
<value>写出meta.json</value>
|
||||
</data>
|
||||
<data name="matchDASH" xml:space="preserve">
|
||||
<value>内容匹配: [white on mediumorchid1]Dynamic Adaptive Streaming over HTTP[/]</value>
|
||||
</data>
|
||||
<data name="checkingLast" xml:space="preserve">
|
||||
<value>验证最后一个分片有效性</value>
|
||||
</data>
|
||||
<data name="parsingStream" xml:space="preserve">
|
||||
<value>正在解析媒体信息...</value>
|
||||
</data>
|
||||
<data name="keyProcessorNotFound" xml:space="preserve">
|
||||
<value>找不到支持的Processor</value>
|
||||
</data>
|
||||
<data name="startDownloading" xml:space="preserve">
|
||||
<value>开始下载...</value>
|
||||
</data>
|
||||
<data name="segmentCountCheckNotPass" xml:space="preserve">
|
||||
<value>分片数量校验不通过, 共{}个,已下载{}.</value>
|
||||
</data>
|
||||
<data name="fixingVTT" xml:space="preserve">
|
||||
<value>正在提取VTT(raw)字幕...</value>
|
||||
</data>
|
||||
<data name="fixingVTTmp4" xml:space="preserve">
|
||||
<value>正在提取VTT(mp4)字幕...</value>
|
||||
</data>
|
||||
<data name="binaryMerge" xml:space="preserve">
|
||||
<value>二进制合并中...</value>
|
||||
</data>
|
||||
<data name="fixingTTMLmp4" xml:space="preserve">
|
||||
<value>正在提取TTML(mp4)字幕...</value>
|
||||
</data>
|
||||
<data name="fixingTTML" xml:space="preserve">
|
||||
<value>正在提取TTML(raw)字幕...</value>
|
||||
</data>
|
||||
<data name="cmd_Input" xml:space="preserve">
|
||||
<value>链接或文件</value>
|
||||
</data>
|
||||
<data name="cmd_header" xml:space="preserve">
|
||||
<value>为HTTP请求设置特定的请求头, 例如:
|
||||
-H "Cookie: mycookie" -H "User-Agent: iOS"</value>
|
||||
</data>
|
||||
<data name="cmd_logLevel" xml:space="preserve">
|
||||
<value>设置日志级别</value>
|
||||
</data>
|
||||
<data name="cmd_autoSelect" xml:space="preserve">
|
||||
<value>自动选择所有类型的最佳轨道</value>
|
||||
</data>
|
||||
<data name="cmd_subOnly" xml:space="preserve">
|
||||
<value>只选取字幕轨道</value>
|
||||
</data>
|
||||
<data name="cmd_threadCount" xml:space="preserve">
|
||||
<value>设置下载线程数</value>
|
||||
</data>
|
||||
<data name="cmd_skipMerge" xml:space="preserve">
|
||||
<value>跳过合并分片</value>
|
||||
</data>
|
||||
<data name="cmd_binaryMerge" xml:space="preserve">
|
||||
<value>二进制合并</value>
|
||||
</data>
|
||||
<data name="cmd_delAfterDone" xml:space="preserve">
|
||||
<value>完成后删除临时文件</value>
|
||||
</data>
|
||||
<data name="cmd_subtitleFix" xml:space="preserve">
|
||||
<value>自动修正字幕</value>
|
||||
</data>
|
||||
<data name="cmd_checkSegmentsCount" xml:space="preserve">
|
||||
<value>检测实际下载的分片数量和预期数量是否匹配</value>
|
||||
</data>
|
||||
<data name="cmd_subFormat" xml:space="preserve">
|
||||
<value>字幕输出类型</value>
|
||||
</data>
|
||||
<data name="cmd_tmpDir" xml:space="preserve">
|
||||
<value>设置临时文件存储目录</value>
|
||||
</data>
|
||||
<data name="cmd_saveDir" xml:space="preserve">
|
||||
<value>设置输出目录</value>
|
||||
</data>
|
||||
<data name="cmd_saveName" xml:space="preserve">
|
||||
<value>设置保存文件名</value>
|
||||
</data>
|
||||
<data name="cmd_uiLanguage" xml:space="preserve">
|
||||
<value>设置UI语言</value>
|
||||
</data>
|
||||
<data name="cmd_skipDownload" xml:space="preserve">
|
||||
<value>跳过下载</value>
|
||||
</data>
|
||||
</root>
|
|
@ -169,4 +169,56 @@
|
|||
<data name="fixingTTML" xml:space="preserve">
|
||||
<value>正在提取TTML(raw)字幕...</value>
|
||||
</data>
|
||||
<data name="cmd_Input" xml:space="preserve">
|
||||
<value>鏈接或文件</value>
|
||||
</data>
|
||||
<data name="cmd_header" xml:space="preserve">
|
||||
<value>為HTTP請求設置特定的請求頭, 例如:
|
||||
-H "Cookie: mycookie" -H "User-Agent: iOS"</value>
|
||||
</data>
|
||||
<data name="cmd_logLevel" xml:space="preserve">
|
||||
<value>設置日誌級別</value>
|
||||
</data>
|
||||
<data name="cmd_autoSelect" xml:space="preserve">
|
||||
<value>自動選擇所有類型的最佳軌道</value>
|
||||
</data>
|
||||
<data name="cmd_subOnly" xml:space="preserve">
|
||||
<value>只選取字幕軌道</value>
|
||||
</data>
|
||||
<data name="cmd_threadCount" xml:space="preserve">
|
||||
<value>設置下載線程數</value>
|
||||
</data>
|
||||
<data name="cmd_skipMerge" xml:space="preserve">
|
||||
<value>跳過合併分片</value>
|
||||
</data>
|
||||
<data name="cmd_binaryMerge" xml:space="preserve">
|
||||
<value>二進制合併</value>
|
||||
</data>
|
||||
<data name="cmd_delAfterDone" xml:space="preserve">
|
||||
<value>完成後刪除臨時文件</value>
|
||||
</data>
|
||||
<data name="cmd_subtitleFix" xml:space="preserve">
|
||||
<value>自動修正字幕</value>
|
||||
</data>
|
||||
<data name="cmd_checkSegmentsCount" xml:space="preserve">
|
||||
<value>檢測實際下載的分片數量和預期數量是否匹配</value>
|
||||
</data>
|
||||
<data name="cmd_subFormat" xml:space="preserve">
|
||||
<value>字幕輸出類型</value>
|
||||
</data>
|
||||
<data name="cmd_tmpDir" xml:space="preserve">
|
||||
<value>設置臨時文件存儲目錄</value>
|
||||
</data>
|
||||
<data name="cmd_saveDir" xml:space="preserve">
|
||||
<value>設置輸出目錄</value>
|
||||
</data>
|
||||
<data name="cmd_saveName" xml:space="preserve">
|
||||
<value>設置保存文件名</value>
|
||||
</data>
|
||||
<data name="cmd_uiLanguage" xml:space="preserve">
|
||||
<value>設置UI語言</value>
|
||||
</data>
|
||||
<data name="cmd_skipDownload" xml:space="preserve">
|
||||
<value>跳過下載</value>
|
||||
</data>
|
||||
</root>
|
|
@ -32,6 +32,7 @@ Global
|
|||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
RESX_NeutralResourcesLanguage = en-US
|
||||
SolutionGuid = {87F963D4-EA06-413D-9372-C726711C32B5}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
using N_m3u8DL_RE.Common.Log;
|
||||
using N_m3u8DL_RE.Common.Resource;
|
||||
using N_m3u8DL_RE.Enum;
|
||||
using System.CommandLine;
|
||||
using System.CommandLine.Binding;
|
||||
using System.Globalization;
|
||||
|
||||
namespace N_m3u8DL_RE.CommandLine
|
||||
{
|
||||
|
||||
internal class CommandInvoker
|
||||
{
|
||||
private readonly static Argument<string> Input = new(name: "input", description: ResString.cmd_Input);
|
||||
private readonly static Option<string?> TmpDir = new(new string[] { "--tmp-dir" }, description: ResString.cmd_tmpDir);
|
||||
private readonly static Option<string?> SaveDir = new(new string[] { "--save-dir" }, description: ResString.cmd_saveDir);
|
||||
private readonly static Option<string?> SaveName = new(new string[] { "--save-name" }, description: ResString.cmd_saveName);
|
||||
private readonly static Option<string?> UILanguage = new(new string[] { "--ui-language" }, description: ResString.cmd_uiLanguage);
|
||||
private readonly static Option<string[]?> Headers = new(new string[] { "--header", "-H" }, description: ResString.cmd_header) { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = false };
|
||||
private readonly static Option<LogLevel> LogLevel = new(name: "--log-level", description: ResString.cmd_logLevel, getDefaultValue: () => Common.Log.LogLevel.INFO);
|
||||
private readonly static Option<SubtitleFormat> SubtitleFormat = new(name: "--sub-format", description: ResString.cmd_subFormat, getDefaultValue: () => Enum.SubtitleFormat.VTT);
|
||||
private readonly static Option<bool> AutoSelect = new(new string[] { "--auto-select" }, description: ResString.cmd_autoSelect, getDefaultValue: () => false);
|
||||
private readonly static Option<bool> SubOnly = new(new string[] { "--sub-only" }, description: ResString.cmd_subOnly, getDefaultValue: () => false);
|
||||
private readonly static Option<int> ThreadCount = new(new string[] { "--thread-count" }, description: ResString.cmd_threadCount, getDefaultValue: () => 8);
|
||||
private readonly static Option<bool> SkipMerge = new(new string[] { "--skip-merge" }, description: ResString.cmd_skipMerge, getDefaultValue: () => false);
|
||||
private readonly static Option<bool> SkipDownload = new(new string[] { "--skip-download" }, description: ResString.cmd_skipDownload, getDefaultValue: () => false);
|
||||
private readonly static Option<bool> BinaryMerge = new(new string[] { "--binary-merge" }, description: ResString.cmd_binaryMerge, getDefaultValue: () => true);
|
||||
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);
|
||||
|
||||
class MyOptionBinder : BinderBase<MyOption>
|
||||
{
|
||||
protected override MyOption GetBoundValue(BindingContext bindingContext)
|
||||
{
|
||||
var option = new MyOption
|
||||
{
|
||||
Input = bindingContext.ParseResult.GetValueForArgument(Input),
|
||||
Headers = bindingContext.ParseResult.GetValueForOption(Headers),
|
||||
LogLevel = bindingContext.ParseResult.GetValueForOption(LogLevel),
|
||||
AutoSelect = bindingContext.ParseResult.GetValueForOption(AutoSelect),
|
||||
SkipMerge = bindingContext.ParseResult.GetValueForOption(SkipMerge),
|
||||
BinaryMerge = bindingContext.ParseResult.GetValueForOption(BinaryMerge),
|
||||
DelAfterDone = bindingContext.ParseResult.GetValueForOption(DelAfterDone),
|
||||
AutoSubtitleFix = bindingContext.ParseResult.GetValueForOption(AutoSubtitleFix),
|
||||
CheckSegmentsCount = bindingContext.ParseResult.GetValueForOption(CheckSegmentsCount),
|
||||
SubtitleFormat = bindingContext.ParseResult.GetValueForOption(SubtitleFormat),
|
||||
SubOnly = bindingContext.ParseResult.GetValueForOption(SubOnly),
|
||||
TmpDir = bindingContext.ParseResult.GetValueForOption(TmpDir),
|
||||
SaveDir = bindingContext.ParseResult.GetValueForOption(SaveDir),
|
||||
SaveName = bindingContext.ParseResult.GetValueForOption(SaveName),
|
||||
ThreadCount = bindingContext.ParseResult.GetValueForOption(ThreadCount),
|
||||
UILanguage = bindingContext.ParseResult.GetValueForOption(UILanguage),
|
||||
SkipDownload = bindingContext.ParseResult.GetValueForOption(SkipDownload),
|
||||
};
|
||||
|
||||
//在这里设置语言
|
||||
|
||||
string loc = "en-US";
|
||||
string currLoc = Thread.CurrentThread.CurrentUICulture.Name;
|
||||
if (currLoc == "zh-CN" || currLoc == "zh-SG") loc = "zh-Hans";
|
||||
else if (currLoc.StartsWith("zh-")) loc = "zh-Hant";
|
||||
|
||||
//以用户选择优先
|
||||
loc = option.UILanguage ?? loc;
|
||||
|
||||
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(loc);
|
||||
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(loc);
|
||||
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(loc);
|
||||
ResString.Culture = CultureInfo.GetCultureInfo(loc);
|
||||
|
||||
return option;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async Task<int> InvokeArgs(string[] args, Func<MyOption, Task> action)
|
||||
{
|
||||
var rootCommand = new RootCommand("N_m3u8DL-RE Beta version: 20220719")
|
||||
{
|
||||
Input, TmpDir, SaveDir, SaveName, ThreadCount, AutoSelect, SkipMerge, SkipDownload, CheckSegmentsCount,
|
||||
BinaryMerge, DelAfterDone, Headers, SubOnly, SubtitleFormat, AutoSubtitleFix, LogLevel, UILanguage
|
||||
};
|
||||
rootCommand.TreatUnmatchedTokensAsErrors = true;
|
||||
rootCommand.SetHandler(async (myOption) => await action(myOption), new MyOptionBinder());
|
||||
|
||||
return await rootCommand.InvokeAsync(args);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
using N_m3u8DL_RE.Common.Log;
|
||||
using N_m3u8DL_RE.Enum;
|
||||
|
||||
namespace N_m3u8DL_RE.CommandLine
|
||||
{
|
||||
internal class MyOption
|
||||
{
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.Input"/>.
|
||||
/// </summary>
|
||||
public string Input { get; set; } = default!;
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.Headers"/>.
|
||||
/// </summary>
|
||||
public string[]? Headers { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.LogLevel"/>.
|
||||
/// </summary>
|
||||
public LogLevel LogLevel { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.AutoSelect"/>.
|
||||
/// </summary>
|
||||
public bool AutoSelect { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.SubOnly"/>.
|
||||
/// </summary>
|
||||
public bool SubOnly { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.ThreadCount"/>.
|
||||
/// </summary>
|
||||
public int ThreadCount { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.SkipMerge"/>.
|
||||
/// </summary>
|
||||
public bool SkipMerge { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.BinaryMerge"/>.
|
||||
/// </summary>
|
||||
public bool BinaryMerge { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.DelAfterDone"/>.
|
||||
/// </summary>
|
||||
public bool DelAfterDone { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.AutoSubtitleFix"/>.
|
||||
/// </summary>
|
||||
public bool AutoSubtitleFix { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.CheckSegmentsCount"/>.
|
||||
/// </summary>
|
||||
public bool CheckSegmentsCount { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.SkipDownload"/>.
|
||||
/// </summary>
|
||||
public bool SkipDownload { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.SubtitleFormat"/>.
|
||||
/// </summary>
|
||||
public SubtitleFormat SubtitleFormat { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.TmpDir"/>.
|
||||
/// </summary>
|
||||
public string? TmpDir { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.SaveDir"/>.
|
||||
/// </summary>
|
||||
public string? SaveDir { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.SaveName"/>.
|
||||
/// </summary>
|
||||
public string? SaveName { get; set; }
|
||||
/// <summary>
|
||||
/// See: <see cref="CommandInvoker.UILanguage"/>.
|
||||
/// </summary>
|
||||
public string? UILanguage { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
using N_m3u8DL_RE.CommandLine;
|
||||
using N_m3u8DL_RE.Enum;
|
||||
using N_m3u8DL_RE.Parser.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -8,6 +11,22 @@ namespace N_m3u8DL_RE.Config
|
|||
{
|
||||
internal class DownloaderConfig
|
||||
{
|
||||
public DownloaderConfig() { }
|
||||
|
||||
public DownloaderConfig(MyOption option)
|
||||
{
|
||||
AutoSubtitleFix = option.AutoSubtitleFix;
|
||||
SkipMerge = option.SkipMerge;
|
||||
BinaryMerge = option.BinaryMerge;
|
||||
DelAfterDone = option.DelAfterDone;
|
||||
CheckSegmentsCount = option.CheckSegmentsCount;
|
||||
SubtitleFormat = option.SubtitleFormat;
|
||||
TmpDir = option.TmpDir;
|
||||
SaveName = option.SaveName;
|
||||
SaveDir = option.SaveDir;
|
||||
ThreadCount = option.ThreadCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 临时文件存储目录
|
||||
/// </summary>
|
||||
|
@ -49,6 +68,10 @@ namespace N_m3u8DL_RE.Config
|
|||
/// </summary>
|
||||
public bool AutoSubtitleFix { get; set; } = true;
|
||||
/// <summary>
|
||||
/// 字幕格式
|
||||
/// </summary>
|
||||
public SubtitleFormat SubtitleFormat { get; set; } = SubtitleFormat.VTT;
|
||||
/// <summary>
|
||||
/// 请求头
|
||||
/// </summary>
|
||||
public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>()
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
<IlcFoldIdenticalMethodBodies>true</IlcFoldIdenticalMethodBodies>
|
||||
<StaticallyLinked Condition="$(RuntimeIdentifier.StartsWith('win'))">true</StaticallyLinked>
|
||||
<TrimMode>full</TrimMode>
|
||||
<TrimmerDefaultAction>link</TrimmerDefaultAction>
|
||||
<IlcTrimMetadata>true</IlcTrimMetadata>
|
||||
<IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
|
||||
<UseSystemResourceKeys>true</UseSystemResourceKeys>
|
||||
<SatelliteResourceLanguages>zh-Hans;zh-Hant;en-US</SatelliteResourceLanguages>
|
||||
<NativeAotCompilerVersion>7.0.0-*</NativeAotCompilerVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
if (segments == null) return false;
|
||||
|
||||
var dirName = $"{NowDateTime:yyyy-MM-dd_HH-mm-ss}_{streamSpec.GroupId}_{streamSpec.Codecs}_{streamSpec.Language}";
|
||||
var tmpDir = DownloaderConfig.TmpDir ?? Path.Combine(Environment.CurrentDirectory, dirName);
|
||||
var tmpDir = Path.Combine(DownloaderConfig.TmpDir ?? Environment.CurrentDirectory, dirName);
|
||||
var saveDir = DownloaderConfig.SaveDir ?? Environment.CurrentDirectory;
|
||||
var saveName = DownloaderConfig.SaveName ?? dirName;
|
||||
var headers = DownloaderConfig.Headers;
|
||||
|
@ -152,12 +152,19 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
foreach (var item in files) File.Delete(item);
|
||||
FileDic.Clear();
|
||||
var index = 0;
|
||||
var path = Path.Combine(tmpDir, index.ToString(pad) + $".fix.{streamSpec.Extension ?? "clip"}");
|
||||
var vttContentFixed = finalVtt.ToStringWithHeader();
|
||||
await File.WriteAllTextAsync(path, vttContentFixed, new UTF8Encoding(false));
|
||||
var path = Path.Combine(tmpDir, index.ToString(pad) + ".fix.vtt");
|
||||
var subContentFixed = finalVtt.ToStringWithHeader();
|
||||
//转换字幕格式
|
||||
if (DownloaderConfig.SubtitleFormat != Enum.SubtitleFormat.VTT)
|
||||
{
|
||||
path = Path.ChangeExtension(path, ".srt");
|
||||
subContentFixed = ConvertUtil.WebVtt2Other(finalVtt, DownloaderConfig.SubtitleFormat);
|
||||
output = Path.ChangeExtension(output, ".srt");
|
||||
}
|
||||
await File.WriteAllTextAsync(path, subContentFixed, new UTF8Encoding(false));
|
||||
FileDic[keys.First()] = new DownloadResult()
|
||||
{
|
||||
ActualContentLength = vttContentFixed.Length,
|
||||
ActualContentLength = subContentFixed.Length,
|
||||
ActualFilePath = path
|
||||
};
|
||||
}
|
||||
|
@ -181,15 +188,22 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
FileDic.Clear();
|
||||
var index = 0;
|
||||
var path = Path.Combine(tmpDir, index.ToString(pad) + ".fix.vtt");
|
||||
var vttContentFixed = finalVtt.ToStringWithHeader();
|
||||
await File.WriteAllTextAsync(path, vttContentFixed, new UTF8Encoding(false));
|
||||
var subContentFixed = finalVtt.ToStringWithHeader();
|
||||
//转换字幕格式
|
||||
if (DownloaderConfig.SubtitleFormat != Enum.SubtitleFormat.VTT)
|
||||
{
|
||||
path = Path.ChangeExtension(path, ".srt");
|
||||
subContentFixed = ConvertUtil.WebVtt2Other(finalVtt, DownloaderConfig.SubtitleFormat);
|
||||
output = Path.ChangeExtension(output, ".srt");
|
||||
}
|
||||
await File.WriteAllTextAsync(path, subContentFixed, new UTF8Encoding(false));
|
||||
FileDic[firstKey] = new DownloadResult()
|
||||
{
|
||||
ActualContentLength = vttContentFixed.Length,
|
||||
ActualContentLength = subContentFixed.Length,
|
||||
ActualFilePath = path
|
||||
};
|
||||
//修改输出后缀
|
||||
output = Path.ChangeExtension(output, ".vtt");
|
||||
output = Path.ChangeExtension(output, Path.GetExtension(path));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,15 +221,22 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
FileDic.Clear();
|
||||
var index = 0;
|
||||
var path = Path.Combine(tmpDir, index.ToString(pad) + ".fix.vtt");
|
||||
var vttContentFixed = finalVtt.ToStringWithHeader();
|
||||
await File.WriteAllTextAsync(path, vttContentFixed, new UTF8Encoding(false));
|
||||
var subContentFixed = finalVtt.ToStringWithHeader();
|
||||
//转换字幕格式
|
||||
if (DownloaderConfig.SubtitleFormat != Enum.SubtitleFormat.VTT)
|
||||
{
|
||||
path = Path.ChangeExtension(path, ".srt");
|
||||
subContentFixed = ConvertUtil.WebVtt2Other(finalVtt, DownloaderConfig.SubtitleFormat);
|
||||
output = Path.ChangeExtension(output, ".srt");
|
||||
}
|
||||
await File.WriteAllTextAsync(path, subContentFixed, new UTF8Encoding(false));
|
||||
FileDic[firstKey] = new DownloadResult()
|
||||
{
|
||||
ActualContentLength = vttContentFixed.Length,
|
||||
ActualContentLength = subContentFixed.Length,
|
||||
ActualFilePath = path
|
||||
};
|
||||
//修改输出后缀
|
||||
output = Path.ChangeExtension(output, ".vtt");
|
||||
output = Path.ChangeExtension(output, Path.GetExtension(path));
|
||||
}
|
||||
|
||||
//自动修复TTML mp4字幕
|
||||
|
@ -237,15 +258,22 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
FileDic.Clear();
|
||||
var index = 0;
|
||||
var path = Path.Combine(tmpDir, index.ToString(pad) + ".fix.vtt");
|
||||
var vttContentFixed = finalVtt.ToStringWithHeader();
|
||||
await File.WriteAllTextAsync(path, vttContentFixed, new UTF8Encoding(false));
|
||||
var subContentFixed = finalVtt.ToStringWithHeader();
|
||||
//转换字幕格式
|
||||
if (DownloaderConfig.SubtitleFormat != Enum.SubtitleFormat.VTT)
|
||||
{
|
||||
path = Path.ChangeExtension(path, ".srt");
|
||||
subContentFixed = ConvertUtil.WebVtt2Other(finalVtt, DownloaderConfig.SubtitleFormat);
|
||||
output = Path.ChangeExtension(output, ".srt");
|
||||
}
|
||||
await File.WriteAllTextAsync(path, subContentFixed, new UTF8Encoding(false));
|
||||
FileDic[firstKey] = new DownloadResult()
|
||||
{
|
||||
ActualContentLength = vttContentFixed.Length,
|
||||
ActualContentLength = subContentFixed.Length,
|
||||
ActualFilePath = path
|
||||
};
|
||||
//修改输出后缀
|
||||
output = Path.ChangeExtension(output, ".vtt");
|
||||
output = Path.ChangeExtension(output, Path.GetExtension(path));
|
||||
}
|
||||
|
||||
//合并
|
||||
|
@ -262,6 +290,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
//删除临时文件夹
|
||||
if (DownloaderConfig.DelAfterDone)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace N_m3u8DL_RE.Enum
|
||||
{
|
||||
internal enum SubtitleFormat
|
||||
{
|
||||
VTT,
|
||||
SRT
|
||||
}
|
||||
}
|
|
@ -7,18 +7,15 @@
|
|||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>0.0.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\N_m3u8DL-RE.Parser\N_m3u8DL-RE.Parser.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Subtitle\" />
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -19,26 +19,32 @@ using N_m3u8DL_RE.Config;
|
|||
using N_m3u8DL_RE.Util;
|
||||
using System.Diagnostics;
|
||||
using N_m3u8DL_RE.DownloadManager;
|
||||
using N_m3u8DL_RE.CommandLine;
|
||||
using System.Reflection;
|
||||
|
||||
namespace N_m3u8DL_RE
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
string loc = "en-US";
|
||||
string currLoc = Thread.CurrentThread.CurrentUICulture.Name;
|
||||
if (currLoc == "zh-TW" || currLoc == "zh-HK" || currLoc == "zh-MO") loc = "zh-TW";
|
||||
else if (currLoc == "zh-CN" || currLoc == "zh-SG") loc = "zh-CN";
|
||||
//设置语言
|
||||
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(loc);
|
||||
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(loc);
|
||||
//Logger.LogLevel = LogLevel.DEBUG;
|
||||
await CommandInvoker.InvokeArgs(args, DoWorkAsync);
|
||||
}
|
||||
|
||||
static async Task DoWorkAsync(MyOption option)
|
||||
{
|
||||
Logger.LogLevel = option.LogLevel;
|
||||
|
||||
try
|
||||
{
|
||||
var parserConfig = new ParserConfig();
|
||||
|
||||
//设置Headers
|
||||
foreach (var item in ConvertUtil.SplitHeaderArrayToDic(option.Headers))
|
||||
{
|
||||
parserConfig.Headers[item.Key] = item.Value;
|
||||
}
|
||||
|
||||
//demo1
|
||||
parserConfig.ContentProcessors.Insert(0, new DemoProcessor());
|
||||
//demo2
|
||||
|
@ -53,19 +59,29 @@ namespace N_m3u8DL_RE
|
|||
//url = "https://rest-as.ott.kaltura.com/api_v3/service/assetFile/action/playManifest/partnerId/147/assetId/1304099/assetType/media/assetFileId/16136929/contextType/PLAYBACK/isAltUrl/False/ks/djJ8MTQ3fMusTFH6PCZpcrfKLQwI-pPm9ex6b6r49wioe32WH2udXeM4reyWIkSDpi7HhvhxBHAHAKiHrcnkmIJQpyAt4MuDBG0ywGQ-jOeqQFcTRQ8BGJGw6g-smSBLwSbo4CCx9M9vWNJX3GkOfhoMAY4yRU-ur3okHiVq1mUJ82XBd_iVqLuzodnc9sJEtcHH0zc5CoPiTq2xor-dq3yDURnZm3isfSN3t9uLIJEW09oE-SJ84DM5GUuFUdbnIV8bdcWUsPicUg-Top1G2D3WcWXq4EvPnwvD8jrC_vsiOpLHf5akAwtdGsJ6__cXUmT7a-QlfjdvaZ5T8UhDLnttHmsxYs2E5c0lh4uOvvJou8dD8iYxUexlPI2j4QUkBRxqOEVLSNV3Y82-5TTRqgnK_uGYXHwk7EAmDws7hbLj2-DJ1heXDcye3OJYdunJgAS-9ma5zmQQNiY_HYh6wj2N1HpCTNAtWWga6R9fC0VgBTZbidW-YwMSGzIvMQfIfWKe15X7Oc_hCs-zGfW9XeRJZrutcWKK_D_HlzpQVBF2vIF3XgaI/a.mpd";
|
||||
//url = "https://dash.akamaized.net/dash264/TestCases/2c/qualcomm/1/MultiResMPEG2.mpd";
|
||||
//url = "http://playertest.longtailvideo.com/adaptive/oceans_aes/oceans_aes.m3u8";
|
||||
//url = "https://cmaf.lln.latam.hbomaxcdn.com/videos/GYPGKMQjoDkVLBQEAAAAo/1/1b5ad5/1_single_J8sExA_1080hi.mpd";
|
||||
url = "https://cmaf.lln.latam.hbomaxcdn.com/videos/GYPGKMQjoDkVLBQEAAAAo/1/1b5ad5/1_single_J8sExA_1080hi.mpd";
|
||||
//url = "https://livesim.dashif.org/dash/vod/testpic_2s/multi_subs.mpd"; //ttml + mp4
|
||||
//url = "http://media.axprod.net/TestVectors/v6-Clear/Manifest_1080p.mpd"; //vtt + mp4
|
||||
url = "https://livesim.dashif.org/dash/vod/testpic_2s/xml_subs.mpd"; //ttml
|
||||
//url = "https://livesim.dashif.org/dash/vod/testpic_2s/xml_subs.mpd"; //ttml
|
||||
//url = "https://storage.googleapis.com/shaka-demo-assets/angel-one-hls/hls.m3u8"; //HLS vtt
|
||||
//url = "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8"; //高级HLS fMP4+VTT
|
||||
//url = "https://events-delivery.apple.com/0205eyyhwbbqexozkwmgccegwnjyrktg/m3u8/vod_index-dpyfrsVksFWjneFiptbXnAMYBtGYbXeZ.m3u8"; //高级HLS fMP4+VTT
|
||||
//url = "https://apionvod5.seezntv.com/ktmain1/cold/CP/55521/202207/media/MIAM61RPSGL150000100_DRM/MIAM61RPSGL150000100_H.m3u8?sid=0000000F50000040000A700000020000";
|
||||
//url = "https://ewcdn12.nowe.com/session/16-5-72579e3-2103014898783810281/Content/DASH_VOS3/VOD/6908/19585/d2afa5fe-e9c8-40f0-8d18-648aaaf292b6/f677841a-9d8f-2ff5-3517-674ba49ef192/manifest.mpd?token=894db5d69931835f82dd8e393974ef9f_1658146180";
|
||||
//url = "https://ols-ww100-cp.akamaized.net/manifest/master/06ee6f68-ee80-11ea-9bc5-02b68fb543c4/65794a72596d6c30496a6f7a4e6a67324e4441774d444173496e42735958526d62334a74496a6f695a47567a6133527663434973496d526c646d6c6a5a565235634755694f694a335a5749694c434a746232526c62434936496e6470626d527664334d694c434a7663315235634755694f694a6a61484a76625755694c434a7663794936496a45774d6934774c6a41694c434a68634841694f69497a4c6a416966513d3d/dash.mpd?cpatoken=exp=1658223027~acl=/manifest/master/06ee6f68-ee80-11ea-9bc5-02b68fb543c4/*~hmac=644c608aac361f688e9b24b0f345c801d0f2d335819431d1873ff7aeac46d6b2&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXZpY2VfaWQiOm51bGwsIndhdGNoX3R5cGUiOiJQUkVNSVVNIiwicHJvZ3JhbV9pZCI6ImUwMWRmYjAyLTM1YmItMTFlOS1hNDI3LTA2YTA0MTdjMWQxZSIsImFkX3RhZyI6ZmFsc2UsInBhcmVudF9wcm9ncmFtX2lkIjoiZmJmMDc2MDYtMzNmYi0xMWU5LWE0MjctMDZhMDQxN2MxZDFlIiwiY2xpZW50X2lkIjoiNGQ3MDViZTQtYTQ5ZS0xMWVhLWJiMzctMDI0MmFjMTMwMDAyIiwidmlkZW9fdHlwZSI6InZvZCIsImdyYW50X3R5cGUiOiJwbGF5X3ZpZGVvIiwidXNlcl9pZCI6ImFhNTMxZWQ2LWM2NTMtNDliYS04NGI1LWFkZDRmNGIzNGMyNyIsImN1cnJlbnRfc2Vjb25kIjowLCJyZXBvcnRfaWQiOiJOU1RHIiwic2NvcGUiOlsicHVibGljOi4qIiwibWU6LioiXSwiZXhwIjoxNjU4Mzk1ODI2LCJkZXRlY3Rpb25faWQiOm51bGwsInZpZGVvX2lkIjoiODc0Yjk0ZDItNzZiYi00YzliLTgzODQtNzJlMTA0NWVjOGMxIiwiaXNzIjoiQXNpYXBsYXktT0F1dGgtU2VydmVyIiwiaWF0IjoxNjU4MTM2NjI2LCJ0ZXJyaXRvcnkiOiJUVyJ9.1juciYIyMNzykXKu-nGLR_cYWvPMEAE9ub-ny7RzFnM";
|
||||
//url = "https://a38avoddashs3ww-a.akamaihd.net/ondemand/iad_2/8e91/f2f2/ec5a/430f-bd7a-0779f4a0189d/685cda75-609c-41c1-86bb-688f4cdb5521_corrected.mpd";
|
||||
url = "https://dcs-vod.mp.lura.live/vod/p/session/manifest.mpd?i=i177610817-nb45239a2-e962-4137-bc70-1790359619e6";
|
||||
//url = "https://theater.kktv.com.tw/98/04000198010001_584b26392f7f7f11fc62299214a55fb7/16113081449d8d5e9960_sub_dash.mpd"; //MPD+VTT
|
||||
//url = "";
|
||||
|
||||
if (args.Length > 0)
|
||||
if (!string.IsNullOrEmpty(option.Input))
|
||||
{
|
||||
url = args[0];
|
||||
url = option.Input;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(url))
|
||||
{
|
||||
url = AnsiConsole.Ask<string>("请输入 [green]URL[/]: ");
|
||||
url = AnsiConsole.Ask<string>("Input [green]URL[/]: ");
|
||||
}
|
||||
|
||||
//流提取器配置
|
||||
|
@ -95,7 +111,27 @@ namespace N_m3u8DL_RE
|
|||
}
|
||||
|
||||
//展示交互式选择框
|
||||
var selectedStreams = PromptUtil.SelectStreams(lists);
|
||||
//var selectedStreams = PromptUtil.SelectStreams(lists);
|
||||
var selectedStreams = new List<StreamSpec>();
|
||||
if (option.AutoSelect)
|
||||
{
|
||||
if (basicStreams.Any())
|
||||
selectedStreams.Add(basicStreams.First());
|
||||
var langs = audios.DistinctBy(a => a.Language).Select(a => a.Language);
|
||||
foreach (var lang in langs)
|
||||
{
|
||||
selectedStreams.Add(audios.Where(a => a.Language == lang).OrderByDescending(a => a.Bandwidth).First());
|
||||
}
|
||||
selectedStreams.AddRange(subs);
|
||||
}
|
||||
else if (option.SubOnly)
|
||||
{
|
||||
selectedStreams.AddRange(subs);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedStreams = PromptUtil.SelectStreams(lists);
|
||||
}
|
||||
//一个以上的话,需要手动重新加载playlist
|
||||
if (lists.Count() > 1)
|
||||
await extractor.FetchPlayListAsync(selectedStreams);
|
||||
|
@ -107,29 +143,33 @@ namespace N_m3u8DL_RE
|
|||
Logger.InfoMarkUp(item.ToString());
|
||||
}
|
||||
|
||||
if (option.SkipDownload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
Console.ReadKey();
|
||||
#endif
|
||||
|
||||
//下载配置
|
||||
var downloadConfig = new DownloaderConfig()
|
||||
var downloadConfig = new DownloaderConfig(option)
|
||||
{
|
||||
Headers = parserConfig.Headers,
|
||||
BinaryMerge = true,
|
||||
DelAfterDone = true,
|
||||
CheckSegmentsCount = true
|
||||
};
|
||||
//开始下载
|
||||
var sdm = new SimpleDownloadManager(downloadConfig);
|
||||
var result = await sdm.StartDownloadAsync(selectedStreams);
|
||||
if (result)
|
||||
Logger.InfoMarkUp("[white on green]成功[/]");
|
||||
Logger.InfoMarkUp("[white on green]Done[/]");
|
||||
else
|
||||
Logger.ErrorMarkUp("[white on red]失败[/]");
|
||||
Logger.ErrorMarkUp("[white on red]Faild[/]");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex.ToString());
|
||||
await Task.Delay(3000);
|
||||
}
|
||||
//Console.ReadKey();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
using N_m3u8DL_RE.Common.Entity;
|
||||
using N_m3u8DL_RE.Common.Log;
|
||||
using N_m3u8DL_RE.Enum;
|
||||
using System.Text;
|
||||
|
||||
namespace N_m3u8DL_RE.Util
|
||||
{
|
||||
internal class ConvertUtil
|
||||
{
|
||||
public static Dictionary<string,string> SplitHeaderArrayToDic(string[]? headers)
|
||||
{
|
||||
Dictionary<string,string> dic = new();
|
||||
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (string header in headers)
|
||||
{
|
||||
var index = header.IndexOf(':');
|
||||
if (index != -1)
|
||||
{
|
||||
dic[header[..index].Trim()] = header[(index + 1)..].Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dic;
|
||||
}
|
||||
|
||||
private static string WebVtt2Srt(WebVttSub vtt)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int index = 1;
|
||||
foreach (var c in vtt.Cues)
|
||||
{
|
||||
sb.AppendLine($"{index++}");
|
||||
sb.AppendLine(c.StartTime.ToString(@"hh\:mm\:ss\,fff") + " --> " + c.EndTime.ToString(@"hh\:mm\:ss\,fff"));
|
||||
sb.AppendLine(c.Payload);
|
||||
sb.AppendLine();
|
||||
}
|
||||
sb.AppendLine();
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string WebVtt2Other(WebVttSub vtt, SubtitleFormat toFormat)
|
||||
{
|
||||
Logger.Debug($"Convert {SubtitleFormat.VTT} ==> {toFormat}");
|
||||
return toFormat switch
|
||||
{
|
||||
SubtitleFormat.VTT => vtt.ToStringWithHeader(),
|
||||
SubtitleFormat.SRT => WebVtt2Srt(vtt),
|
||||
_ => throw new NotSupportedException($"{toFormat} not supported!")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<Directives>
|
||||
<Application>
|
||||
<Assembly Name="N_m3u8DL-RE" Dynamic="Required All"/>
|
||||
<!--<Assembly Name="N_m3u8DL-RE" Dynamic="Required All"/>
|
||||
<Assembly Name="N_m3u8DL-RE.Common" Dynamic="Required All"/>
|
||||
<Assembly Name="N_m3u8DL-RE.Parser" Dynamic="Required All"/>
|
||||
<Assembly Name="N_m3u8DL-RE.Parser" Dynamic="Required All"/>-->
|
||||
</Application>
|
||||
</Directives>
|
Loading…
Reference in New Issue