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