protected override void AddSubtitleFilter(bool isSourceFilterPresent) { VideoSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <VideoSettings>() ?? new VideoSettings(); int preferredSubtitleLcid = settings.PreferredSubtitleLanguage; var fileSystemResourceAccessor = _resourceAccessor as IFileSystemResourceAccessor; if (fileSystemResourceAccessor != null) { ServiceRegistration.Get <ILogger>().Debug("{0}: Adding MPC-HC subtitle engine", PlayerTitle); SubtitleStyle defStyle = new SubtitleStyle(); defStyle.Load(); MpcSubtitles.SetDefaultStyle(ref defStyle, false); IntPtr upDevice = SkinContext.Device.NativePointer; string filename = fileSystemResourceAccessor.ResourcePathName; MpcSubtitles.LoadSubtitles(upDevice, _displaySize, filename, _graphBuilder, @".\", preferredSubtitleLcid); if (settings.EnableSubtitles) { MpcSubtitles.SetEnable(true); } } AddClosedCaptionsFilter(); }
// Load subtitles directly from a TextAsset public static void loadFromXML(TextAsset file) { XmlDocument root = new XmlDocument(); root.LoadXml(file.text); // Styles Dictionary <string, SubtitleStyle> styles = new Dictionary <string, SubtitleStyle>(); foreach (XmlNode node in root.SelectNodes("subtitles/styles/style")) { string key = node.Attributes.GetNamedItem("id").Value; float red = float.Parse(node.Attributes.GetNamedItem("red").Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); float green = float.Parse(node.Attributes.GetNamedItem("green").Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); float blue = float.Parse(node.Attributes.GetNamedItem("blue").Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); SubtitleStyle style = new SubtitleStyle(new Color(red, green, blue), (node.Attributes.GetNamedItem("italic").Value == "1")); styles[key] = style; } // Texts foreach (XmlNode node in root.SelectNodes("subtitles/texts/subtitle")) { string key = node.Attributes.GetNamedItem("id").Value; string message = node.InnerText; message = message.Replace("\n", ""); message = message.Replace("\r", ""); message = message.Replace("\t", ""); float duration = float.Parse(node.Attributes.GetNamedItem("duration").Value, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); string style = node.Attributes.GetNamedItem("style").Value; SubtitleInfo info = new SubtitleInfo(message, duration, Color.white, true); if (styles.ContainsKey(style)) { info.color = styles[style].color; info.italic = styles[style].italic; } subtitlesDatabase[key] = info; } }
protected override void AddSubtitleFilter(bool isSourceFilterPresent) { VideoSettings settings = ServiceRegistration.Get<ISettingsManager>().Load<VideoSettings>() ?? new VideoSettings(); int preferredSubtitleLcid = settings.PreferredSubtitleLanguage; ServiceRegistration.Get<ILogger>().Debug("{0}: Adding MPC-HC subtitle engine", PlayerTitle); SubtitleStyle defStyle = new SubtitleStyle(); defStyle.Load(); MpcSubtitles.SetDefaultStyle(ref defStyle, false); IntPtr upDevice = SkinContext.Device.NativePointer; string filename = string.Empty; string paths; if (GetSubtitlePath(out paths, out filename)) { MpcSubtitles.LoadSubtitles(upDevice, _displaySize, filename, _graphBuilder, paths, preferredSubtitleLcid); MpcSubtitles.SetEnable(settings.EnableSubtitles); } }
protected override void AddSubtitleFilter(bool isSourceFilterPresent) { VideoSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <VideoSettings>() ?? new VideoSettings(); int preferredSubtitleLcid = settings.PreferredSubtitleLanguage; ServiceRegistration.Get <ILogger>().Debug("{0}: Adding MPC-HC subtitle engine", PlayerTitle); SubtitleStyle defStyle = new SubtitleStyle(); defStyle.Load(); MpcSubtitles.SetDefaultStyle(ref defStyle, false); IntPtr upDevice = SkinContext.Device.NativePointer; string filename = string.Empty; string paths; if (GetSubtitlePath(out paths, out filename)) { MpcSubtitles.LoadSubtitles(upDevice, _displaySize, filename, _graphBuilder, paths, preferredSubtitleLcid); MpcSubtitles.SetEnable(settings.EnableMpcSubtitlesEngine); } }
public static extern void SetDefaultStyle([In] ref SubtitleStyle style, bool overrideUserStyle);
/// <summary> /// Creates an PNG image for given Subtitle caption /// </summary> /// <param name="caption">Subtitle caption</param> /// <param name="style">Subtitle style</param> /// <param name="number">Caption number</param> /// <param name="videoWidth">Video width</param> /// <param name="videoHeight">Video height</param> /// <param name="baseFName">File base name</param> /// <returns>Generated PNG image</returns> public static ImageHolder CreateImage(SubCaption caption, SubtitleStyle style, int number, int videoWidth, int videoHeight, string baseFName) { _boldStyle = false; _italicStyle = false; _underlineStyle = false; _strikeStyle = false; var result = new ImageHolder(); if (string.IsNullOrEmpty(baseFName)) { return(new ImageHolder()); } var basePath = Path.GetDirectoryName(baseFName); var baseName = Path.GetFileNameWithoutExtension(baseFName); if (string.IsNullOrEmpty(basePath) || string.IsNullOrEmpty(baseName)) { return(new ImageHolder()); } result.FileName = $"{Path.Combine(basePath, baseName)}_{number:00000}.png"; var imgSize = new SizeF(); var styleFontStyle = FontStyle.Regular; if (style.Bold) { styleFontStyle = styleFontStyle | FontStyle.Bold; } if (style.Italic) { styleFontStyle = styleFontStyle | FontStyle.Italic; } var styleFont = new Font(style.FontName, style.FontSize, styleFontStyle, GraphicsUnit.Point); var stringFormat = new StringFormat(); var lineSizes = new List <SizeF>(); var rawText = Regex.Replace(caption.Text, "</*?(?:i|b)>", "", RegexOptions.Singleline | RegexOptions.Multiline); var rawTextLines = rawText.Split(new[] { Environment.NewLine }, StringSplitOptions.None); foreach (var rawTextLine in rawTextLines) { using (var rawLinePath = new GraphicsPath()) { rawLinePath.AddString(rawTextLine, styleFont.FontFamily, (int)styleFontStyle, styleFont.SizeInPoints, new PointF(), stringFormat); lineSizes.Add(rawLinePath.GetBounds().Size); } } var textLines = caption.Text.Split(new[] { Environment.NewLine }, StringSplitOptions.None); var lastLineBreak = 0f; foreach (var lineSize in lineSizes) { imgSize.Height += lineSize.Height; lastLineBreak = lineSize.Height / 3; imgSize.Height += lastLineBreak; if (lineSize.Width > imgSize.Width) { imgSize.Width = lineSize.Width; } } imgSize.Height -= lastLineBreak; if (imgSize.IsEmpty) { return(new ImageHolder()); } stringFormat.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, 1) }); RectangleF whiteSpace; using (Image img = new Bitmap((int)imgSize.Width, (int)imgSize.Height, PixelFormat.Format32bppArgb)) { using (var g = Graphics.FromImage(img)) { var origin = new RectangleF(new PointF(0f, 0f), imgSize); var regions2 = g.MeasureCharacterRanges(" .", styleFont, origin, stringFormat); if (!regions2.Any()) { return(new ImageHolder()); } whiteSpace = regions2[0].GetBounds(g); } } var wordpath = new GraphicsPath(); var wordPathShadow = new GraphicsPath(); var shadowOffset = style.Shadow; var wStart = new RectangleF { Y = 0, X = 0 }; var wStartShadow = wStart; wStartShadow.Offset(shadowOffset, shadowOffset); for (var i = 0; i < textLines.Length; i++) { var textLine = textLines[i]; var lineSize = lineSizes[i]; wStart.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); wStartShadow.Offset(imgSize.Width / 2 - lineSize.Width / 2, 0); var words = textLine.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); foreach (var word in words) { using (GraphicsPath singleWord = new GraphicsPath(), singleWordShadow = new GraphicsPath()) { string lWord; var fontStyle = GetStyleFont(word, out lWord, styleFontStyle); if (string.IsNullOrEmpty(lWord)) { continue; } singleWord.AddString(lWord, styleFont.FontFamily, (int)fontStyle, styleFont.SizeInPoints, wStart.Location, stringFormat); singleWordShadow.AddString(lWord, styleFont.FontFamily, (int)fontStyle, styleFont.SizeInPoints, wStartShadow.Location, stringFormat); wordpath.AddPath(singleWord, false); wordPathShadow.AddPath(singleWordShadow, false); wStart.Offset(singleWord.GetBounds().Size.Width + whiteSpace.Size.Width, 0); wStartShadow.Offset(singleWordShadow.GetBounds().Size.Width + whiteSpace.Size.Width, 0); } } wStart.X = 0; wStart.Offset(0, lineSize.Height + lineSize.Height / 3); wStartShadow.X = shadowOffset; wStartShadow.Offset(0, lineSize.Height + lineSize.Height / 3); } imgSize.Width = wordPathShadow.GetBounds().Right; imgSize.Height = wordPathShadow.GetBounds().Bottom; using (Image img = new Bitmap((int)imgSize.Width + style.MarginL + style.MarginR, (int)imgSize.Height + style.MarginV * 2, PixelFormat.Format32bppArgb)) { using (var g = Graphics.FromImage(img)) { g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAlias; g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.InterpolationMode = InterpolationMode.High; Brush primBrush = new SolidBrush(style.PrimaryColor); Brush shadowBrush = new SolidBrush(Color.FromArgb(64, style.BackColor)); var outPen = new Pen(style.OutlineColor) { Alignment = PenAlignment.Outset }; if (style.BorderStyle == 1) { outPen.Width = style.Outline == 0 && style.Shadow > 0 ? 1 : style.Outline; style.Outline = (int)outPen.Width; } g.FillRectangle(Brushes.Transparent, 0, 0, img.Width, img.Height); // draw shadow if (style.BorderStyle == 1 && style.Shadow > 0) { g.FillPath(shadowBrush, wordPathShadow); } g.FillPath(primBrush, wordpath); // draw outline if (style.BorderStyle == 1 && style.Outline > 0) { g.DrawPath(outPen, wordpath); } } img.Save(result.FileName, ImageFormat.Png); result.FileName = Path.GetFileName(result.FileName); result.Height = img.Height; result.Width = img.Width; } return(result); }