kodi
WebVTTHandler.h
1 /*
2  * Copyright (C) 2005-2021 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "guilib/GUIColorManager.h"
12 #include "utils/ColorUtils.h"
13 #include "utils/RegExp.h"
14 
15 #include <deque>
16 #include <map>
17 #include <memory>
18 #include <stdio.h>
19 #include <string>
20 #include <string_view>
21 #include <utility>
22 #include <vector>
23 
24 enum class WebvttSection
25 {
26  UNDEFINED = 0,
27  STYLE,
28  STYLE_CONTENT,
29  REGION,
30  CUE,
31  CUE_TEXT,
32  CUE_METADATA,
33  NOTE
34 };
35 
36 enum class WebvttAlign
37 {
38  AUTO = 0,
39  LEFT,
40  CENTER,
41  RIGHT,
42  START,
43  END
44 };
45 
46 enum class WebvttVAlign
47 {
48  HORIZONTAL = 0,
49  VERTICAL_RL,
50  VERTICAL_LR,
51 };
52 
53 enum class TextAlignment
54 {
55  TOP_LEFT = 0,
56  TOP_CENTER,
57  TOP_RIGHT,
58  SUB_LEFT,
59  SUB_CENTER,
60  SUB_RIGHT
61 };
62 
64 {
65  double value = 0;
66  bool isAuto = true;
67 };
68 
70 {
71  std::string id;
72  std::string regionId;
73  WebvttVAlign verticalAlign;
74  bool snapToLines;
75  webvttAutoValue line;
76  webvttAutoValue position;
77  WebvttAlign positionAlign;
78  double size;
79  WebvttAlign align;
80 
81  bool operator==(webvttCueSettings const& other) const
82  {
83  return this->verticalAlign == other.verticalAlign && this->snapToLines == other.snapToLines &&
84  this->line.isAuto == other.line.isAuto && this->line.value == other.line.value &&
85  this->position.isAuto == other.position.isAuto &&
86  this->position.value == other.position.value &&
87  this->positionAlign == other.positionAlign && this->size == other.size &&
88  this->align == other.align;
89  }
90 };
91 
93 {
94  std::string text;
95  std::string textRaw; // Text without tags
96  webvttCueSettings cueSettings;
97  double startTime;
98  double stopTime;
99  bool useMargins;
100  int marginLeft;
101  int marginRight;
102  int marginVertical;
103  TextAlignment textAlign;
104 };
105 
106 enum class WebvttSelector
107 {
108  ANY = 0,
109  ID,
110  TYPE,
111  CLASS,
112  ATTRIBUTE,
113  UNSUPPORTED
114 };
115 
117 {
118  webvttCssStyle() {}
119  webvttCssStyle(WebvttSelector selectorType,
120  const std::string& selectorName,
121  const std::string& colorHexRGB)
122  : m_selectorType{selectorType},
123  m_selectorName{selectorName},
124  // Color hex values need to be in BGR format
125  m_color(colorHexRGB.substr(4, 2) + colorHexRGB.substr(2, 2) + colorHexRGB.substr(0, 2))
126  {
127  }
128 
129  WebvttSelector m_selectorType = WebvttSelector::ANY;
130  std::string m_selectorName;
131  std::string m_color;
132  bool m_isFontBold = false;
133  bool m_isFontItalic = false;
134  bool m_isFontUnderline = false;
135 };
136 
137 struct tagToken
138 {
139  std::string m_token; // Entire tag
140  std::string m_tag;
141  std::string m_timestampTag;
142  std::string m_annotation;
143  std::vector<std::string> m_classes;
144  bool m_isClosing;
145 };
146 
148 {
149 public:
150  CWebVTTHandler(){};
151  ~CWebVTTHandler(){};
152 
156  bool Initialize();
157 
158  /*
159  * \brief Reset handler data
160  */
161  void Reset();
162 
166  bool CheckSignature(const std::string& data);
167 
173  void DecodeLine(std::string line, std::vector<subtitleData>* subList);
174 
175  /*
176  * \brief Return true if the margins are handled by the parser.
177  */
178  bool IsForcedMargins() const { return !m_overridePositions; }
179 
180  /*
181  * \brief Set the period start pts to sync subtitles
182  */
183  void SetPeriodStart(double pts) { m_offset = pts; }
184 
185 protected:
186  void CalculateTextPosition(std::string& subtitleText);
187  void ConvertSubtitle(std::string& text);
188  void GetCueSettings(std::string& cueSettings);
189  subtitleData m_subtitleData;
190 
191 private:
192  bool IsCueLine(std::string& line);
193  void GetCueData(std::string& cueText);
194  std::string GetCueSettingValue(const std::string& propName,
195  std::string& text,
196  const std::string& defaultValue);
197  std::string GetCueCssValue(const std::string& cssPropName, std::string& line);
198  void AddDefaultCssClasses();
199  void InsertCssStyleStartTag(const tagToken& tag,
200  std::string& text,
201  int& pos,
202  int flagTags[],
203  std::deque<std::pair<std::string, webvttCssStyle*>>& cssTagsOpened);
204  void InsertCssStyleCloseTag(const tagToken& tag,
205  std::string& text,
206  int& pos,
207  int flagTags[],
208  std::deque<std::pair<std::string, webvttCssStyle*>>& cssTagsOpened,
209  webvttCssStyle& baseStyle);
210  bool GetBaseStyle(webvttCssStyle& style);
211  void ConvertAddSubtitle(std::vector<subtitleData>* subList);
212  void LoadColors();
213  double GetTimeFromRegexTS(CRegExp& regex, int indexStart = 1);
214 
215  // Last subtitle data added, must persist and be updated between all demuxer packages
216  std::unique_ptr<subtitleData> m_lastSubtitleData;
217 
218  std::string m_previousLines[3];
219  bool m_overrideStyle{false};
220  bool m_overridePositions{false};
221  WebvttSection m_currentSection{WebvttSection::UNDEFINED};
222  CRegExp m_cueTimeRegex;
223  CRegExp m_timeRegex;
224  std::map<std::string, CRegExp> m_cuePropsMapRegex;
225  CGUIColorManager m_colorManager;
226  CRegExp m_tagsRegex;
227  CRegExp m_cueCssTagRegex;
228  std::map<std::string, CRegExp> m_cueCssStyleMapRegex;
229  std::vector<std::string> m_feedCssSelectorNames;
230  webvttCssStyle m_feedCssStyle;
231  std::map<WebvttSelector, std::map<std::string, webvttCssStyle>> m_cssSelectors;
232 
233  bool m_CSSColorsLoaded{false};
234  std::vector<std::pair<std::string, UTILS::COLOR::ColorInfo>> m_CSSColors;
235  double m_offset{0.0};
236 };
Definition: WebVTTHandler.h:137
Definition: RegExp.h:27
Definition: WebVTTHandler.h:116
Definition: WebVTTHandler.h:69
Definition: WebVTTHandler.h:63
Definition: WebVTTHandler.h:147
Definition: LibInputPointer.h:13
Definition: GUIColorManager.h:30
Definition: WebVTTHandler.h:92