jellyfin/MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs

61 lines
2.3 KiB
C#
Raw Normal View History

using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.MediaEncoding.Subtitles
{
/// <summary>
/// TTML subtitle writer.
/// </summary>
2023-05-22 20:48:09 +00:00
public partial class TtmlWriter : ISubtitleWriter
{
2023-05-22 20:48:09 +00:00
[GeneratedRegex(@"\\n", RegexOptions.IgnoreCase)]
private static partial Regex NewLineEscapeRegex();
/// <inheritdoc />
public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken)
{
// Example: https://github.com/zmalltalker/ttml2vtt/blob/master/data/sample.xml
// Parser example: https://github.com/mozilla/popcorn-js/blob/master/parsers/parserTTML/popcorn.parserTTML.js
using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
{
writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
writer.WriteLine("<tt xmlns=\"http://www.w3.org/ns/ttml\" xmlns:tts=\"http://www.w3.org/2006/04/ttaf1#styling\" lang=\"no\">");
writer.WriteLine("<head>");
writer.WriteLine("<styling>");
writer.WriteLine("<style id=\"italic\" tts:fontStyle=\"italic\" />");
writer.WriteLine("<style id=\"left\" tts:textAlign=\"left\" />");
writer.WriteLine("<style id=\"center\" tts:textAlign=\"center\" />");
writer.WriteLine("<style id=\"right\" tts:textAlign=\"right\" />");
writer.WriteLine("</styling>");
writer.WriteLine("</head>");
writer.WriteLine("<body>");
writer.WriteLine("<div>");
foreach (var trackEvent in info.TrackEvents)
{
var text = trackEvent.Text;
2023-05-22 20:48:09 +00:00
text = NewLineEscapeRegex().Replace(text, "<br/>");
writer.WriteLine(
"<p begin=\"{0}\" dur=\"{1}\">{2}</p>",
trackEvent.StartPositionTicks,
trackEvent.EndPositionTicks - trackEvent.StartPositionTicks,
text);
}
writer.WriteLine("</div>");
writer.WriteLine("</body>");
2019-01-07 23:27:46 +00:00
writer.WriteLine("</tt>");
}
}
}
}