优化图形字幕处理 #109
This commit is contained in:
parent
fa70b15322
commit
fffc5666d8
|
@ -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) 20230111";
|
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20230323";
|
||||||
|
|
||||||
[GeneratedRegex("((best|worst)\\d*|all)")]
|
[GeneratedRegex("((best|worst)\\d*|all)")]
|
||||||
private static partial Regex ForStrRegex();
|
private static partial Regex ForStrRegex();
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
ConcurrentDictionary<MediaSegment, DownloadResult?> FileDic = new();
|
ConcurrentDictionary<MediaSegment, DownloadResult?> FileDic = new();
|
||||||
|
|
||||||
var segments = streamSpec.Playlist?.MediaParts.SelectMany(m => m.MediaSegments);
|
var segments = streamSpec.Playlist?.MediaParts.SelectMany(m => m.MediaSegments);
|
||||||
if (segments == null) return false;
|
if (segments == null || !segments.Any()) return false;
|
||||||
if (segments.Count() == 1) speedContainer.SingleSegment = true;
|
if (segments.Count() == 1) speedContainer.SingleSegment = true;
|
||||||
|
|
||||||
var type = streamSpec.MediaType ?? Common.Enum.MediaType.VIDEO;
|
var type = streamSpec.MediaType ?? Common.Enum.MediaType.VIDEO;
|
||||||
|
@ -441,19 +441,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
var files = FileDic.OrderBy(s => s.Key.Index).Select(s => s.Value).Select(v => v!.ActualFilePath).ToArray();
|
var files = FileDic.OrderBy(s => s.Key.Index).Select(s => s.Value).Select(v => v!.ActualFilePath).ToArray();
|
||||||
|
|
||||||
//处理图形字幕
|
//处理图形字幕
|
||||||
if (finalVtt.Cues.All(v => v.Payload.StartsWith("Base64::")))
|
await SubtitleUtil.TryWriteImagePngsAsync(finalVtt, tmpDir);
|
||||||
{
|
|
||||||
Logger.WarnMarkUp(ResString.processImageSub);
|
|
||||||
var _pad = "0".PadLeft(finalVtt.Cues.Count().ToString().Length, '0');
|
|
||||||
var _i = 0;
|
|
||||||
foreach (var img in finalVtt.Cues)
|
|
||||||
{
|
|
||||||
var base64 = img.Payload[8..];
|
|
||||||
var name = _i++.ToString(_pad) + ".png";
|
|
||||||
await File.WriteAllBytesAsync(Path.Combine(tmpDir, name), Convert.FromBase64String(base64));
|
|
||||||
img.Payload = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var item in files) File.Delete(item);
|
foreach (var item in files) File.Delete(item);
|
||||||
FileDic.Clear();
|
FileDic.Clear();
|
||||||
|
@ -504,19 +492,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
var files = FileDic.OrderBy(s => s.Key.Index).Select(s => s.Value).Select(v => v!.ActualFilePath).ToArray();
|
var files = FileDic.OrderBy(s => s.Key.Index).Select(s => s.Value).Select(v => v!.ActualFilePath).ToArray();
|
||||||
|
|
||||||
//处理图形字幕
|
//处理图形字幕
|
||||||
if (finalVtt.Cues.All(v => v.Payload.StartsWith("Base64::")))
|
await SubtitleUtil.TryWriteImagePngsAsync(finalVtt, tmpDir);
|
||||||
{
|
|
||||||
Logger.WarnMarkUp(ResString.processImageSub);
|
|
||||||
var _pad = "0".PadLeft(finalVtt.Cues.Count().ToString().Length, '0');
|
|
||||||
var _i = 0;
|
|
||||||
foreach (var img in finalVtt.Cues)
|
|
||||||
{
|
|
||||||
var base64 = img.Payload[8..];
|
|
||||||
var name = _i++.ToString(_pad) + ".png";
|
|
||||||
await File.WriteAllBytesAsync(Path.Combine(tmpDir, name), Convert.FromBase64String(base64));
|
|
||||||
img.Payload = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var item in files) File.Delete(item);
|
foreach (var item in files) File.Delete(item);
|
||||||
FileDic.Clear();
|
FileDic.Clear();
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
{
|
{
|
||||||
name = GetUnixTimestamp(segment.DateTime!.Value).ToString();
|
name = GetUnixTimestamp(segment.DateTime!.Value).ToString();
|
||||||
}
|
}
|
||||||
else if (hls && segment.Index > 10)
|
else if (hls)
|
||||||
{
|
{
|
||||||
name = segment.Index.ToString();
|
name = segment.Index.ToString();
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
//TryReceiveAll可以稍微缓解一下
|
//TryReceiveAll可以稍微缓解一下
|
||||||
source.TryReceiveAll(out IList<List<MediaSegment>>? segmentsList);
|
source.TryReceiveAll(out IList<List<MediaSegment>>? segmentsList);
|
||||||
var segments = segmentsList!.SelectMany(s => s);
|
var segments = segmentsList!.SelectMany(s => s);
|
||||||
|
if (segments == null || !segments.Any()) continue;
|
||||||
var segmentsDuration = segments.Sum(s => s.Duration);
|
var segmentsDuration = segments.Sum(s => s.Duration);
|
||||||
Logger.DebugMarkUp(string.Join(",", segments.Select(sss => GetSegmentName(sss, false, false))));
|
Logger.DebugMarkUp(string.Join(",", segments.Select(sss => GetSegmentName(sss, false, false))));
|
||||||
|
|
||||||
|
@ -594,6 +595,10 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
File.Delete(inputFilePath);
|
File.Delete(inputFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//处理图形字幕
|
||||||
|
await SubtitleUtil.TryWriteImagePngsAsync(currentVtt, tmpDir);
|
||||||
|
|
||||||
var subText = currentVtt.ToVtt();
|
var subText = currentVtt.ToVtt();
|
||||||
if (outputExt == ".srt")
|
if (outputExt == ".srt")
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
using N_m3u8DL_RE.Common.Entity;
|
||||||
|
using N_m3u8DL_RE.Common.Log;
|
||||||
|
using N_m3u8DL_RE.Common.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace N_m3u8DL_RE.Util
|
||||||
|
{
|
||||||
|
internal class SubtitleUtil
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 写出图形字幕PNG文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="finalVtt"></param>
|
||||||
|
/// <param name="tmpDir">临时目录</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<bool> TryWriteImagePngsAsync(WebVttSub? finalVtt, string tmpDir)
|
||||||
|
{
|
||||||
|
if (finalVtt != null && finalVtt.Cues.Any(v => v.Payload.StartsWith("Base64::")))
|
||||||
|
{
|
||||||
|
Logger.WarnMarkUp(ResString.processImageSub);
|
||||||
|
var _i = 0;
|
||||||
|
foreach (var img in finalVtt.Cues.Where(v => v.Payload.StartsWith("Base64::")))
|
||||||
|
{
|
||||||
|
var name = $"{_i++}.png";
|
||||||
|
var dest = "";
|
||||||
|
for (; File.Exists(dest = Path.Combine(tmpDir, name)); name = $"{_i++}.png") ;
|
||||||
|
var base64 = img.Payload[8..];
|
||||||
|
await File.WriteAllBytesAsync(dest, Convert.FromBase64String(base64));
|
||||||
|
img.Payload = name;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue