优化图形字幕处理 #109

This commit is contained in:
nilaoda 2023-03-23 22:42:55 +08:00
parent fa70b15322
commit fffc5666d8
4 changed files with 50 additions and 29 deletions

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) 20230111";
public const string VERSION_INFO = "N_m3u8DL-RE (Beta version) 20230323";
[GeneratedRegex("((best|worst)\\d*|all)")]
private static partial Regex ForStrRegex();

View File

@ -106,7 +106,7 @@ namespace N_m3u8DL_RE.DownloadManager
ConcurrentDictionary<MediaSegment, DownloadResult?> FileDic = new();
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;
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();
//处理图形字幕
if (finalVtt.Cues.All(v => v.Payload.StartsWith("Base64::")))
{
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;
}
}
await SubtitleUtil.TryWriteImagePngsAsync(finalVtt, tmpDir);
foreach (var item in files) File.Delete(item);
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();
//处理图形字幕
if (finalVtt.Cues.All(v => v.Payload.StartsWith("Base64::")))
{
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;
}
}
await SubtitleUtil.TryWriteImagePngsAsync(finalVtt, tmpDir);
foreach (var item in files) File.Delete(item);
FileDic.Clear();

View File

@ -122,7 +122,7 @@ namespace N_m3u8DL_RE.DownloadManager
{
name = GetUnixTimestamp(segment.DateTime!.Value).ToString();
}
else if (hls && segment.Index > 10)
else if (hls)
{
name = segment.Index.ToString();
}
@ -200,6 +200,7 @@ namespace N_m3u8DL_RE.DownloadManager
//TryReceiveAll可以稍微缓解一下
source.TryReceiveAll(out IList<List<MediaSegment>>? segmentsList);
var segments = segmentsList!.SelectMany(s => s);
if (segments == null || !segments.Any()) continue;
var segmentsDuration = segments.Sum(s => s.Duration);
Logger.DebugMarkUp(string.Join(",", segments.Select(sss => GetSegmentName(sss, false, false))));
@ -594,6 +595,10 @@ namespace N_m3u8DL_RE.DownloadManager
File.Delete(inputFilePath);
}
}
//处理图形字幕
await SubtitleUtil.TryWriteImagePngsAsync(currentVtt, tmpDir);
var subText = currentVtt.ToVtt();
if (outputExt == ".srt")
{

View File

@ -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;
}
}
}