1#include <QRegularExpression>
5#include "libmythbase/mythconfig.h"
12 static const QRegularExpression
kQuotes{
"^\"|\"$"};
16 QByteArray ba = uri.toLatin1();
17 QUrl url = QUrl::fromEncoded(ba);
18 return url.toString();
21 QString
RelativeURI(
const QString& surl,
const QString& spath)
23 QUrl url = QUrl(surl);
24 QUrl path = QUrl(spath);
26 if (!path.isRelative())
29 return url.resolved(path).toString();
34 int p = line.indexOf(QLatin1String(
":"));
38 QStringList list = line.mid(
p + 1).split(
',');
39 for (
const auto & it : std::as_const(list))
41 QString arg = it.trimmed();
42 if (arg.startsWith(attr))
44 int pos = arg.indexOf(QLatin1String(
"="));
47 return arg.mid(pos+1);
59 int p = line.indexOf(QLatin1String(
":"));
63 for ( ; i < line.size(); i++)
64 if (!line[i].isNumber())
68 target = line.mid(
p + 1, i -
p - 1).toInt();
78 int p = line.indexOf(QLatin1String(
":"));
82 for ( ; i < line.size(); i++)
83 if (!line[i].isNumber())
87 target = line.mid(
p + 1, i -
p - 1).toInt();
107 LOG(VB_RECORD, LOG_ERR, loc +
108 "#EXT-X-VERSION: no protocol version found, should be version 1.");
113 if (version < 1 || version > 7)
115 LOG(VB_RECORD, LOG_ERR, loc +
116 QString(
"#EXT-X-VERSION is %1, but we only understand 1 to 7")
134 LOG(VB_RECORD, LOG_INFO, loc +
135 QString(
"Parsing stream from %1").arg(url));
149 LOG(VB_RECORD, LOG_INFO, loc +
150 "#EXT-X-STREAM-INF: No PROGRAM-ID=<value>, using 1");
161 LOG(VB_RECORD, LOG_ERR, loc +
162 "#EXT-X-STREAM-INF: expected BANDWIDTH=<value>");
165 bandwidth = attr.toInt();
169 LOG(VB_RECORD, LOG_ERR, loc +
170 "#EXT-X-STREAM-INF: bandwidth cannot be 0");
184 if (!audio.isEmpty())
187 LOG(VB_RECORD, LOG_INFO, loc +
188 QString(
"#EXT-X-STREAM-INF: attribute AUDIO=%1").arg(audio));
193 if (!video.isEmpty())
196 LOG(VB_RECORD, LOG_INFO, loc +
197 QString(
"#EXT-X-STREAM-INF: attribute VIDEO=%1").arg(video));
201 LOG(VB_RECORD, LOG_INFO, loc +
202 QString(
"bandwidth adaptation detected (program-id=%1, bandwidth=%2)")
203 .arg(
id).arg(bandwidth));
217 LOG(VB_RECORD, LOG_INFO, loc + QString(
"Parsing EXT-X-MEDIA line"));
243 LOG(VB_RECORD, LOG_ERR, loc +
"expected #EXT-X-TARGETDURATION:<s>");
251 int& duration, QString& title,
268 int p = line.indexOf(QLatin1String(
":"));
271 LOG(VB_RECORD, LOG_ERR, loc +
272 QString(
"ParseSegmentInformation: Missing ':' in '%1'")
277 QStringList list = line.mid(
p + 1).split(
',');
282 LOG(VB_RECORD, LOG_ERR, loc +
283 QString(
"ParseSegmentInformation: Missing arguments in '%1'")
290 const QString& val = list[0];
293 int duration_seconds = val.toInt(&ok);
296 duration = duration_seconds * 1000;
300 LOG(VB_RECORD, LOG_ERR, loc +
301 QString(
"ParseSegmentInformation: invalid duration in '%1'")
308 double d = val.toDouble(&ok);
311 LOG(VB_RECORD, LOG_ERR, loc +
312 QString(
"ParseSegmentInformation: invalid duration in '%1'")
316 duration =
static_cast<int>(
d * 1000);
319 if (list.size() >= 2)
329 const QString& line,
const QString& loc)
342 LOG(VB_RECORD, LOG_ERR, loc +
"expected #EXT-X-MEDIA-SEQUENCE:<s>");
350 [[maybe_unused]]
bool& aesmsg,
351 const QString& loc, QString &path, QString &iv)
366 LOG(VB_RECORD, LOG_ERR, loc +
"#EXT-X-KEY: expected METHOD=<value>");
370 if (attr.startsWith(QLatin1String(
"NONE")))
375 LOG(VB_RECORD, LOG_ERR, loc +
"#EXT-X-KEY: URI not expected");
382 if (!parsed_iv.isEmpty())
384 LOG(VB_RECORD, LOG_ERR, loc +
"#EXT-X-KEY: IV not expected");
390 else if (attr.startsWith(QLatin1String(
"AES-128")))
395 LOG(VB_RECORD, LOG_INFO, loc +
396 "playback of AES-128 encrypted HTTP Live media detected.");
402 LOG(VB_RECORD, LOG_ERR, loc +
"#EXT-X-KEY: URI not found for "
403 "encrypted HTTP Live media in AES-128");
408 path =
DecodedURI(uri.remove(QChar(QLatin1Char(
'"'))));
411 LOG(VB_RECORD, LOG_DEBUG, QString(
"M3U::ParseKey #EXT-X-KEY: %1").arg(line));
412 LOG(VB_RECORD, LOG_DEBUG, QString(
"M3U::ParseKey path:%1 IV:%2").arg(path, iv));
414 else if (attr.startsWith(QLatin1String(
"SAMPLE-AES")))
416 LOG(VB_RECORD, LOG_ERR, loc +
"encryption SAMPLE-AES not supported.");
423 LOG(VB_RECORD, LOG_ERR, loc +
424 "invalid encryption type, only NONE "
426 "and AES-128 are supported"
463 LOG(VB_RECORD, LOG_ERR, loc +
464 QString(
"Attribute URI not present in: #EXT-X-MAP %1")
477 int p = line.indexOf(QLatin1String(
":"));
480 LOG(VB_RECORD, LOG_ERR, loc +
481 QString(
"ParseProgramDateTime: Missing ':' in '%1'")
486 QString dt_string = line.mid(
p+1);
505 int pos = line.indexOf(QLatin1String(
":"));
508 LOG(VB_RECORD, LOG_ERR, loc +
509 QString(
"ParseAllowCache: missing ':' in '%1'")
513 QString answer = line.mid(pos+1, 3);
514 if (answer.size() < 2)
516 LOG(VB_RECORD, LOG_ERR, loc +
"#EXT-X-ALLOW-CACHE, ignoring ...");
519 do_cache = (!answer.startsWith(QLatin1String(
"NO")));
539 LOG(VB_RECORD, LOG_ERR, loc +
"expected #EXT-X-DISCONTINUITY-SEQUENCE:<s>");
543 LOG(VB_RECORD, LOG_DEBUG, loc + QString(
"#EXT-X-DISCONTINUITY-SEQUENCE %1")
551 LOG(VB_RECORD, LOG_DEBUG, loc + QString(
"#EXT-X-DISCONTINUITY %1")
564 LOG(VB_RECORD, LOG_INFO, loc +
" video on demand (vod) mode");
582 LOG(VB_RECORD, LOG_DEBUG, loc + QString(
"#EXT-X-INDEPENDENT-SEGMENTS %1")
static const iso6937table * d
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
bool ParseDecimalValue(const QString &line, int &target)
Return the decimal argument in a line of type: blah:<decimal> presence of value <decimal> is compulso...
bool ParseDiscontinuitySequence(const QString &line, const QString &loc, int &discontinuity_sequence)
bool ParseVersion(const QString &line, const QString &loc, int &version)
bool ParseAllowCache(const QString &line, const QString &loc, bool &do_cache)
bool ParseEndList(const QString &loc, bool &is_vod)
bool ParseMap(const QString &line, const QString &loc, QString &uri)
QString RelativeURI(const QString &surl, const QString &spath)
bool ParseTargetDuration(const QString &line, const QString &loc, int &duration)
QString ParseAttributes(const QString &line, const char *attr)
bool ParseIndependentSegments(const QString &line, const QString &loc)
bool ParseMedia(const QString &line, const QString &loc, QString &media_type, QString &group_id, QString &uri, QString &name)
bool ParseMediaSequence(int64_t &sequence_num, const QString &line, const QString &loc)
bool ParseDiscontinuity(const QString &line, const QString &loc)
bool ParseProgramDateTime(const QString &line, const QString &loc, QDateTime &dt)
static const QRegularExpression kQuotes
bool ParseSegmentInformation(int version, const QString &line, int &duration, QString &title, const QString &loc)
QString DecodedURI(const QString &uri)
bool ParseKey(int version, const QString &line, bool &aesmsg, const QString &loc, QString &path, QString &iv)
bool ParseStreamInformation(const QString &line, const QString &url, const QString &loc, int &id, uint64_t &bandwidth, QString &audio, QString &video)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.