自动计算stpp字幕时间轴
This commit is contained in:
parent
02efb814e9
commit
4ba8f48835
|
@ -29,6 +29,8 @@ namespace N_m3u8DL_RE.Common.Entity
|
|||
public string? VideoRange { get; set; }
|
||||
//补充信息-特征
|
||||
public string? Characteristics { get; set; }
|
||||
//发布时间(仅MPD需要)
|
||||
public DateTime? PublishTime { get; set; }
|
||||
|
||||
//外部轨道GroupId (后续寻找对应轨道信息)
|
||||
public string? AudioId { get; set; }
|
||||
|
|
|
@ -24,9 +24,9 @@ namespace N_m3u8DL_RE.Common.Entity
|
|||
/// </summary>
|
||||
/// <param name="textBytes"></param>
|
||||
/// <returns></returns>
|
||||
public static WebVttSub Parse(byte[] textBytes)
|
||||
public static WebVttSub Parse(byte[] textBytes, long BaseTimestamp = 0L)
|
||||
{
|
||||
return Parse(Encoding.UTF8.GetString(textBytes));
|
||||
return Parse(Encoding.UTF8.GetString(textBytes), BaseTimestamp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -35,9 +35,9 @@ namespace N_m3u8DL_RE.Common.Entity
|
|||
/// <param name="textBytes"></param>
|
||||
/// <param name="encoding"></param>
|
||||
/// <returns></returns>
|
||||
public static WebVttSub Parse(byte[] textBytes, Encoding encoding)
|
||||
public static WebVttSub Parse(byte[] textBytes, Encoding encoding, long BaseTimestamp = 0L)
|
||||
{
|
||||
return Parse(encoding.GetString(textBytes));
|
||||
return Parse(encoding.GetString(textBytes), BaseTimestamp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -45,7 +45,7 @@ namespace N_m3u8DL_RE.Common.Entity
|
|||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public static WebVttSub Parse(string text)
|
||||
public static WebVttSub Parse(string text, long BaseTimestamp = 0L)
|
||||
{
|
||||
if (!text.Trim().StartsWith("WEBVTT"))
|
||||
throw new Exception("Bad vtt!");
|
||||
|
@ -98,6 +98,22 @@ namespace N_m3u8DL_RE.Common.Entity
|
|||
}
|
||||
}
|
||||
|
||||
if (BaseTimestamp != 0)
|
||||
{
|
||||
foreach (var item in webSub.Cues)
|
||||
{
|
||||
if (item.StartTime.TotalMilliseconds - BaseTimestamp >= 0)
|
||||
{
|
||||
item.StartTime = TimeSpan.FromMilliseconds(item.StartTime.TotalMilliseconds - BaseTimestamp);
|
||||
item.EndTime = TimeSpan.FromMilliseconds(item.EndTime.TotalMilliseconds - BaseTimestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return webSub;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,6 +190,12 @@ namespace N_m3u8DL_RE.Parser.Extractor
|
|||
streamSpec.Channels = audioChannelConfiguration.Attribute("value")?.Value;
|
||||
}
|
||||
|
||||
//发布时间
|
||||
if (!string.IsNullOrEmpty(publishTime))
|
||||
{
|
||||
streamSpec.PublishTime = DateTime.Parse(publishTime);
|
||||
}
|
||||
|
||||
|
||||
//第一种形式 SegmentBase
|
||||
var segmentBaseElement = representation.Elements().Where(e => e.Name.LocalName == "SegmentBase").FirstOrDefault();
|
||||
|
|
|
@ -118,7 +118,7 @@ namespace Mp4SubtitleParser
|
|||
return MultiElementsFixRegex().Matches(xml).Select(m => m.Value).ToList();
|
||||
}
|
||||
|
||||
public static WebVttSub ExtractFromMp4s(IEnumerable<string> items, long segTimeMs)
|
||||
public static WebVttSub ExtractFromMp4s(IEnumerable<string> items, long segTimeMs, long baseTimestamp = 0L)
|
||||
{
|
||||
//read ttmls
|
||||
List<string> xmls = new List<string>();
|
||||
|
@ -156,10 +156,10 @@ namespace Mp4SubtitleParser
|
|||
segIndex++;
|
||||
}
|
||||
|
||||
return ExtractSub(xmls);
|
||||
return ExtractSub(xmls, baseTimestamp);
|
||||
}
|
||||
|
||||
public static WebVttSub ExtractFromTTMLs(IEnumerable<string> items, long segTimeMs)
|
||||
public static WebVttSub ExtractFromTTMLs(IEnumerable<string> items, long segTimeMs, long baseTimestamp = 0L)
|
||||
{
|
||||
//read ttmls
|
||||
List<string> xmls = new List<string>();
|
||||
|
@ -178,10 +178,10 @@ namespace Mp4SubtitleParser
|
|||
segIndex++;
|
||||
}
|
||||
|
||||
return ExtractSub(xmls);
|
||||
return ExtractSub(xmls, baseTimestamp);
|
||||
}
|
||||
|
||||
private static WebVttSub ExtractSub(List<string> xmls)
|
||||
private static WebVttSub ExtractSub(List<string> xmls, long baseTimestamp)
|
||||
{
|
||||
//parsing
|
||||
var xmlDoc = new XmlDocument();
|
||||
|
@ -306,7 +306,7 @@ namespace Mp4SubtitleParser
|
|||
vtt.AppendLine();
|
||||
}
|
||||
|
||||
return WebVttSub.Parse(vtt.ToString());
|
||||
return WebVttSub.Parse(vtt.ToString(), baseTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
StreamExtractor StreamExtractor;
|
||||
List<StreamSpec> SelectedSteams;
|
||||
DateTime NowDateTime;
|
||||
DateTime? PublishDateTime;
|
||||
bool STOP_FLAG = false;
|
||||
int WAIT_SEC = 0; //刷新间隔
|
||||
ConcurrentDictionary<int, int> RecordingDurDic = new(); //已录制时长
|
||||
|
@ -46,6 +47,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
this.DownloaderConfig = downloaderConfig;
|
||||
Downloader = new SimpleDownloader(DownloaderConfig);
|
||||
NowDateTime = DateTime.Now;
|
||||
PublishDateTime = selectedSteams.FirstOrDefault()?.PublishTime;
|
||||
StreamExtractor = streamExtractor;
|
||||
SelectedSteams = selectedSteams;
|
||||
}
|
||||
|
@ -115,6 +117,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
|
||||
private async Task<bool> RecordStreamAsync(StreamSpec streamSpec, ProgressTask task, SpeedContainer speedContainer, ISourceBlock<List<MediaSegment>> source)
|
||||
{
|
||||
var baseTimestamp = PublishDateTime == null ? 0L : (long)(PublishDateTime.Value.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds;
|
||||
//mp4decrypt
|
||||
var mp4decrypt = DownloaderConfig.MyOptions.DecryptionBinaryPath!;
|
||||
var mp4InitFile = "";
|
||||
|
@ -321,6 +324,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
if (firstSub)
|
||||
{
|
||||
currentVtt = MP4VttUtil.ExtractSub(mp4s, timescale);
|
||||
firstSub = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -337,11 +341,17 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
var mp4s = FileDic.Values.Select(v => v!.ActualFilePath).Where(p => p.EndsWith(".ttml")).OrderBy(s => s).ToArray();
|
||||
if (firstSub)
|
||||
{
|
||||
currentVtt = MP4TtmlUtil.ExtractFromTTMLs(mp4s, 0);
|
||||
if (baseTimestamp != 0)
|
||||
{
|
||||
var total = segments.Sum(s => s.Duration);
|
||||
baseTimestamp -= (long)TimeSpan.FromSeconds(total).TotalMilliseconds;
|
||||
}
|
||||
currentVtt = MP4TtmlUtil.ExtractFromTTMLs(mp4s, 0, baseTimestamp);
|
||||
firstSub = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var finalVtt = MP4TtmlUtil.ExtractFromTTMLs(mp4s, 0);
|
||||
var finalVtt = MP4TtmlUtil.ExtractFromTTMLs(mp4s, 0, baseTimestamp);
|
||||
currentVtt.AddCuesFromOne(finalVtt);
|
||||
}
|
||||
}
|
||||
|
@ -358,11 +368,17 @@ namespace N_m3u8DL_RE.DownloadManager
|
|||
var mp4s = FileDic.Values.Select(v => v!.ActualFilePath).Where(p => p.EndsWith(".m4s")).OrderBy(s => s).ToArray();
|
||||
if (firstSub)
|
||||
{
|
||||
currentVtt = MP4TtmlUtil.ExtractFromMp4s(mp4s, 0);
|
||||
if (baseTimestamp != 0)
|
||||
{
|
||||
var total = segments.Sum(s => s.Duration);
|
||||
baseTimestamp -= (long)TimeSpan.FromSeconds(total).TotalMilliseconds;
|
||||
}
|
||||
currentVtt = MP4TtmlUtil.ExtractFromMp4s(mp4s, 0, baseTimestamp);
|
||||
firstSub = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var finalVtt = MP4TtmlUtil.ExtractFromMp4s(mp4s, 0);
|
||||
var finalVtt = MP4TtmlUtil.ExtractFromMp4s(mp4s, 0, baseTimestamp);
|
||||
currentVtt.AddCuesFromOne(finalVtt);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue