MythTV  master
iptvtuningdata.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 #ifndef IPTV_TUNING_DATA_H
3 #define IPTV_TUNING_DATA_H
4 
5 #include <array>
6 
7 // Qt headers
8 #include <QApplication>
9 #include <QString>
10 #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
11 #include <QStringConverter>
12 #endif
13 #include <QUrl>
14 
15 // MythTV headers
18 #include "libmythtv/mythtvexp.h"
20 
22 {
23  public:
24  enum FECType : std::uint8_t
25  {
30  };
31 
32  enum IPTVType : std::uint8_t
33  {
34  kData = 1,
41  };
42 
43  enum IPTVProtocol : std::uint8_t
44  {
45  inValid = 0,
46  udp,
47  rtp,
50  http_hls
51  };
52 
54  {
55  m_bitrate.fill(0);
56  }
57 
58  IPTVTuningData(const QString &data_url, IPTVProtocol protocol) :
59  m_dataUrl(data_url), m_protocol(protocol)
60  {
61  m_bitrate.fill(0);
62  }
63 
64  IPTVTuningData(const QString &data_url, uint data_bitrate,
65  const FECType fec_type,
66  const QString &fec_url0, uint fec_bitrate0,
67  const QString &fec_url1, uint fec_bitrate1) :
68  m_dataUrl(data_url),
69  m_fecType(fec_type), m_fecUrl0(fec_url0), m_fecUrl1(fec_url1)
70  {
71  GuessProtocol();
72  m_bitrate[0] = data_bitrate;
73  m_bitrate[1] = fec_bitrate0;
74  m_bitrate[2] = fec_bitrate1;
75  }
76 
77  IPTVTuningData(const QString &data_url, uint data_bitrate,
78  const QString &fec_type,
79  const QString &fec_url0, uint fec_bitrate0,
80  const QString &fec_url1, uint fec_bitrate1,
81  const IPTVProtocol protocol) :
82  m_dataUrl(data_url),
83  m_fecUrl0(fec_url0), m_fecUrl1(fec_url1),
84  m_protocol(protocol)
85  {
86  m_bitrate[0] = data_bitrate;
87  m_bitrate[1] = fec_bitrate0;
88  m_bitrate[2] = fec_bitrate1;
89  if (fec_type.toLower() == "rfc2733")
90  m_fecType = kRFC2733;
91  else if (fec_type.toLower() == "rfc5109")
92  m_fecType = kRFC5109;
93  else if (fec_type.toLower() == "smpte2022")
94  m_fecType = kSMPTE2022;
95  else
96  {
97  m_fecUrl0.clear();
98  m_fecUrl1.clear();
99  }
100  }
101 
102  QString GetDeviceKey(void) const
103  {
104  const QUrl u = GetDataURL();
105  if (IsHLS())
106  return QString("%1(%2)").arg(u.toString()).arg(GetBitrate(0));
107  if (IsHTTPTS() || IsRTSP())
108  return QString("%1").arg(u.toString());
109  return QString("%1:%2:%3")
110  .arg(u.host(),u.userInfo(),QString::number(u.port())).toLower();
111  }
112 
113  QString GetDeviceName(void) const
114  {
115  return QString("[data]%1[fectype]%2[fec0]%3[fec1]%4%5")
116  .arg(GetDataURL().toString(),
117  GetFECTypeString(1),
118  GetFECURL1().toString(),
119  GetFECURL1().toString(),
120  GetBitrate(0) ? QString("-%1").arg(GetBitrate(0)) : "");
121  }
122 
123  bool operator==(const IPTVTuningData &other) const
124  {
125  return GetDeviceName() == other.GetDeviceName();
126  }
127 
128  bool operator!=(const IPTVTuningData &other) const
129  {
130  return GetDeviceName() != other.GetDeviceName();
131  }
132 
133  void SetDataURL(const QUrl &url)
134  {
135  m_dataUrl = url;
136  GuessProtocol();
137  }
138 
139  QUrl GetDataURL(void) const { return m_dataUrl; }
140  QUrl GetFECURL0(void) const { return m_fecUrl0; }
141  QUrl GetFECURL1(void) const { return m_fecUrl1; }
142  QUrl GetURL(uint i) const
143  {
144  if (0 == i)
145  return GetDataURL();
146  if (1 == i)
147  return GetFECURL0();
148  if (2 == i)
149  return GetFECURL1();
150  return {};
151  }
152  uint GetBitrate(uint i) const { return m_bitrate[i]; }
153 
154  FECType GetFECType(void) const { return m_fecType; }
155 
156  QString GetFECTypeString(uint i) const
157  {
158  if (0 == i)
159  return "data";
160  switch (m_fecType)
161  {
162  case kNone: return {};
163  case kRFC2733: return QString("rfc2733-%1").arg(i);
164  case kRFC5109: return QString("rfc5109-%1").arg(i);
165  case kSMPTE2022: return QString("smpte2022-%1").arg(i);
166  }
167  return {};
168  }
169 
170  static uint GetURLCount(void) { return 3; }
171 
172  bool IsValid(void) const
173  {
174  bool ret = (m_dataUrl.isValid() && (IsUDP() || IsRTP() || IsRTSP() || IsHLS() || IsHTTPTS()));
175 
176  LOG(VB_CHANNEL, LOG_DEBUG, QString("IPTVTuningdata (%1): IsValid = %2")
177  .arg(m_dataUrl.toString(),
178  ret ? "true" : "false"));
179 
180  return ret;
181  }
182 
183  bool IsUDP(void) const
184  {
185  return (m_protocol == udp);
186  }
187 
188  bool IsRTP(void) const
189  {
190  return (m_protocol == rtp);
191  }
192 
193  bool IsRTSP(void) const
194  {
195  return (m_protocol == rtsp);
196  }
197 
198  bool IsHLS() const
199  {
200  return (m_protocol == http_hls);
201  }
202 
203  bool IsHTTPTS() const
204  {
205  return (m_protocol == http_ts);
206  }
207 
208  void GuessProtocol(void)
209  {
210  if (!m_dataUrl.isValid())
211  m_protocol = IPTVTuningData::inValid; // NOLINT(bugprone-branch-clone)
212  else if (m_dataUrl.scheme() == "udp")
213  m_protocol = IPTVTuningData::udp;
214  else if (m_dataUrl.scheme() == "rtp")
215  m_protocol = IPTVTuningData::rtp;
216  else if (m_dataUrl.scheme() == "rtsp")
217  m_protocol = IPTVTuningData::rtsp;
218  else if (((m_dataUrl.scheme() == "http") || (m_dataUrl.scheme() == "https")) && IsHLSPlaylist())
219  m_protocol = IPTVTuningData::http_hls;
220  else if ((m_dataUrl.scheme() == "http") || (m_dataUrl.scheme() == "https"))
221  m_protocol = IPTVTuningData::http_ts;
222  else
223  m_protocol = IPTVTuningData::inValid;
224  }
225 
227  {
228  return m_protocol;
229  }
230 
231  protected:
232  bool IsHLSPlaylist(void) const
233  {
234  if (QCoreApplication::instance() == nullptr)
235  {
236  LOG(VB_GENERAL, LOG_ERR, QString("IsHLSPlaylist - No QCoreApplication!!"));
237  return false;
238  }
239 
240  QString url = m_dataUrl.toString();
241  auto path = m_dataUrl.path();
242 
243  // check url is valid for a playlist before downloading (see trac ticket #12856)
244  if(path.endsWith(".m3u8", Qt::CaseInsensitive) ||
245  path.endsWith(".m3u", Qt::CaseInsensitive))
246  {
247  LOG(VB_RECORD, LOG_INFO, QString("IsHLSPlaylist url ends with either .m3u8 or .m3u %1").arg(url));
248  }
249  else
250  {
251  // not a valid playlist so just return false
252  LOG(VB_RECORD, LOG_INFO, QString("IsHLSPlaylist url does not end with either .m3u8 or .m3u %1").arg(url));
253  return false;
254  }
255 
256  QByteArray buffer;
257 
258  MythSingleDownload downloader;
259  downloader.DownloadURL(url, &buffer, 5s, 0, 10000);
260  if (buffer.isEmpty())
261  {
262  LOG(VB_GENERAL, LOG_ERR, QString("IsHLSPlaylist - Open Failed: %1\n\t\t\t%2")
263  .arg(downloader.ErrorString(), url));
264  return false;
265  }
266 
267  QTextStream text(&buffer);
268 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
269  text.setCodec("UTF-8");
270 #else
271  text.setEncoding(QStringConverter::Utf8);
272 #endif
273  return (HLSReader::IsValidPlaylist(text));
274  }
275 
276  protected:
277  QUrl m_dataUrl;
278  FECType m_fecType {kNone};
279  QUrl m_fecUrl0;
280  QUrl m_fecUrl1;
281  std::array<uint,3> m_bitrate {};
282  IPTVProtocol m_protocol {inValid};
283 };
284 
285 #endif // IPTV_TUNING_DATA_H
IPTVTuningData::IPTVTuningData
IPTVTuningData(const QString &data_url, uint data_bitrate, const FECType fec_type, const QString &fec_url0, uint fec_bitrate0, const QString &fec_url1, uint fec_bitrate1)
Definition: iptvtuningdata.h:64
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
IPTVTuningData::IPTVProtocol
IPTVProtocol
Definition: iptvtuningdata.h:43
IPTVTuningData::IsRTSP
bool IsRTSP(void) const
Definition: iptvtuningdata.h:193
IPTVTuningData::rtsp
@ rtsp
Definition: iptvtuningdata.h:48
IPTVTuningData::FECType
FECType
Definition: iptvtuningdata.h:24
IPTVTuningData::IPTVTuningData
IPTVTuningData()
Definition: iptvtuningdata.h:53
IPTVTuningData::kSMPTE2022_1
@ kSMPTE2022_1
Definition: iptvtuningdata.h:39
mythtvexp.h
IPTVTuningData::m_fecUrl1
QUrl m_fecUrl1
Definition: iptvtuningdata.h:280
IPTVTuningData::GetFECType
FECType GetFECType(void) const
Definition: iptvtuningdata.h:154
IPTVTuningData::GetDataURL
QUrl GetDataURL(void) const
Definition: iptvtuningdata.h:139
IPTVTuningData::GetFECURL0
QUrl GetFECURL0(void) const
Definition: iptvtuningdata.h:140
IPTVTuningData::IPTVTuningData
IPTVTuningData(const QString &data_url, uint data_bitrate, const QString &fec_type, const QString &fec_url0, uint fec_bitrate0, const QString &fec_url1, uint fec_bitrate1, const IPTVProtocol protocol)
Definition: iptvtuningdata.h:77
IPTVTuningData::IsRTP
bool IsRTP(void) const
Definition: iptvtuningdata.h:188
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
IPTVTuningData::operator==
bool operator==(const IPTVTuningData &other) const
Definition: iptvtuningdata.h:123
mythsingledownload.h
IPTVTuningData::GetURLCount
static uint GetURLCount(void)
Definition: iptvtuningdata.h:170
IPTVTuningData::IPTVType
IPTVType
Definition: iptvtuningdata.h:32
IPTVTuningData::GetDeviceKey
QString GetDeviceKey(void) const
Definition: iptvtuningdata.h:102
IPTVTuningData::IsUDP
bool IsUDP(void) const
Definition: iptvtuningdata.h:183
IPTVTuningData::http_hls
@ http_hls
Definition: iptvtuningdata.h:50
HLSReader::IsValidPlaylist
static bool IsValidPlaylist(QTextStream &text)
Definition: HLSReader.cpp:264
mythlogging.h
IPTVTuningData::IsHTTPTS
bool IsHTTPTS() const
Definition: iptvtuningdata.h:203
IPTVTuningData::m_fecUrl0
QUrl m_fecUrl0
Definition: iptvtuningdata.h:279
MythSingleDownload::DownloadURL
bool DownloadURL(const QUrl &url, QByteArray *buffer, std::chrono::seconds timeout=30s, uint redirs=0, qint64 maxsize=0, QString *final_url=nullptr)
Definition: mythsingledownload.cpp:14
IPTVTuningData::kRFC2733_2
@ kRFC2733_2
Definition: iptvtuningdata.h:36
IPTVTuningData::GetDeviceName
QString GetDeviceName(void) const
Definition: iptvtuningdata.h:113
IPTVTuningData::GetFECURL1
QUrl GetFECURL1(void) const
Definition: iptvtuningdata.h:141
IPTVTuningData::m_dataUrl
QUrl m_dataUrl
Definition: iptvtuningdata.h:277
IPTVTuningData
Definition: iptvtuningdata.h:21
IPTVTuningData::udp
@ udp
Definition: iptvtuningdata.h:46
IPTVTuningData::rtp
@ rtp
Definition: iptvtuningdata.h:47
uint
unsigned int uint
Definition: compat.h:81
IPTVTuningData::kSMPTE2022_2
@ kSMPTE2022_2
Definition: iptvtuningdata.h:40
MTV_PUBLIC
#define MTV_PUBLIC
Definition: mythtvexp.h:15
IPTVTuningData::IsHLS
bool IsHLS() const
Definition: iptvtuningdata.h:198
IPTVTuningData::kRFC2733
@ kRFC2733
Definition: iptvtuningdata.h:27
MythSingleDownload
Definition: mythsingledownload.h:25
IPTVTuningData::kRFC5109
@ kRFC5109
Definition: iptvtuningdata.h:28
IPTVTuningData::SetDataURL
void SetDataURL(const QUrl &url)
Definition: iptvtuningdata.h:133
IPTVTuningData::GuessProtocol
void GuessProtocol(void)
Definition: iptvtuningdata.h:208
IPTVTuningData::kRFC2733_1
@ kRFC2733_1
Definition: iptvtuningdata.h:35
IPTVTuningData::GetFECTypeString
QString GetFECTypeString(uint i) const
Definition: iptvtuningdata.h:156
MythSingleDownload::ErrorString
QString ErrorString(void) const
Definition: mythsingledownload.h:36
IPTVTuningData::kRFC5109_2
@ kRFC5109_2
Definition: iptvtuningdata.h:38
IPTVTuningData::IsValid
bool IsValid(void) const
Definition: iptvtuningdata.h:172
IPTVTuningData::kRFC5109_1
@ kRFC5109_1
Definition: iptvtuningdata.h:37
IPTVTuningData::operator!=
bool operator!=(const IPTVTuningData &other) const
Definition: iptvtuningdata.h:128
IPTVTuningData::IPTVTuningData
IPTVTuningData(const QString &data_url, IPTVProtocol protocol)
Definition: iptvtuningdata.h:58
IPTVTuningData::GetProtocol
IPTVProtocol GetProtocol(void) const
Definition: iptvtuningdata.h:226
IPTVTuningData::GetBitrate
uint GetBitrate(uint i) const
Definition: iptvtuningdata.h:152
IPTVTuningData::IsHLSPlaylist
bool IsHLSPlaylist(void) const
Definition: iptvtuningdata.h:232
IPTVTuningData::http_ts
@ http_ts
Definition: iptvtuningdata.h:49
IPTVTuningData::inValid
@ inValid
Definition: iptvtuningdata.h:45
IPTVTuningData::GetURL
QUrl GetURL(uint i) const
Definition: iptvtuningdata.h:142
IPTVTuningData::kSMPTE2022
@ kSMPTE2022
Definition: iptvtuningdata.h:29
HLSReader.h
IPTVTuningData::kNone
@ kNone
Definition: iptvtuningdata.h:26