diff --git a/pvr.iptvsimple/addon.xml.in b/pvr.iptvsimple/addon.xml.in index adebeec3..bb3fac74 100644 --- a/pvr.iptvsimple/addon.xml.in +++ b/pvr.iptvsimple/addon.xml.in @@ -1,7 +1,7 @@ @ADDON_DEPENDS@ diff --git a/pvr.iptvsimple/changelog.txt b/pvr.iptvsimple/changelog.txt index 2b1b261c..00898984 100644 --- a/pvr.iptvsimple/changelog.txt +++ b/pvr.iptvsimple/changelog.txt @@ -1,3 +1,7 @@ +v21.8.7 +- Fix #KODIPROP parsing from playlists +- Fix wrong fix to manifest user-agent header for inputstream.adaptive + v21.8.6 - Always add mimetype for inputstream.adaptive - Better handled user-agent header for inputstream.adaptive use cases diff --git a/src/iptvsimple/PlaylistLoader.cpp b/src/iptvsimple/PlaylistLoader.cpp index d05abf8f..eca0343c 100644 --- a/src/iptvsimple/PlaylistLoader.cpp +++ b/src/iptvsimple/PlaylistLoader.cpp @@ -552,7 +552,7 @@ void PlaylistLoader::ParseAndAddChannelGroups(const std::string& groupNamesListS void PlaylistLoader::ParseSinglePropertyIntoChannel(const std::string& line, Channel& channel, const std::string& markerName) { - const std::string value = ReadMarkerValue(line, markerName); + const std::string value = ReadMarkerValue(line, markerName, markerName != KODIPROP_MARKER); auto pos = value.find('='); if (pos != std::string::npos) { @@ -604,7 +604,9 @@ void PlaylistLoader::ReloadPlayList() } } -std::string PlaylistLoader::ReadMarkerValue(const std::string& line, const std::string& markerName) +std::string PlaylistLoader::ReadMarkerValue(const std::string& line, + const std::string& markerName, + bool isCheckDelimiters /* = true */) { size_t markerStart = line.find(markerName); if (markerStart != std::string::npos) @@ -613,21 +615,29 @@ std::string PlaylistLoader::ReadMarkerValue(const std::string& line, const std:: markerStart += marker.length(); if (markerStart < line.length()) { - if (marker == M3U_GROUP_MARKER && line[markerStart] != '"') + size_t markerEnd; + if (isCheckDelimiters) { - //For this case we just want to return the full string without splitting it - //This is because groups use semi-colons and not spaces as a delimiter - return line.substr(markerStart, line.length()); - } + if (marker == M3U_GROUP_MARKER && line[markerStart] != '"') + { + //For this case we just want to return the full string without splitting it + //This is because groups use semi-colons and not spaces as a delimiter + return line.substr(markerStart, line.length()); + } - char find = ' '; - if (line[markerStart] == '"') - { - find = '"'; - markerStart++; + char find = ' '; + if (line[markerStart] == '"') + { + find = '"'; + markerStart++; + } + markerEnd = line.find(find, markerStart); + if (markerEnd == std::string::npos) + { + markerEnd = line.length(); + } } - size_t markerEnd = line.find(find, markerStart); - if (markerEnd == std::string::npos) + else { markerEnd = line.length(); } diff --git a/src/iptvsimple/PlaylistLoader.h b/src/iptvsimple/PlaylistLoader.h index b2cdaa6c..6366a50d 100644 --- a/src/iptvsimple/PlaylistLoader.h +++ b/src/iptvsimple/PlaylistLoader.h @@ -75,7 +75,7 @@ namespace iptvsimple void ReloadPlayList(); private: - static std::string ReadMarkerValue(const std::string& line, const std::string& markerName); + static std::string ReadMarkerValue(const std::string& line, const std::string& markerName, bool isCheckDelimiters = true); static void ParseSinglePropertyIntoChannel(const std::string& line, iptvsimple::data::Channel& channel, const std::string& markerName); std::string ParseIntoChannel(const std::string& line, iptvsimple::data::Channel& channel, data::MediaEntry& mediaEntry, int epgTimeShift, int catchupCorrectionSecs, bool xeevCatchup); diff --git a/src/iptvsimple/utilities/StreamUtils.cpp b/src/iptvsimple/utilities/StreamUtils.cpp index cda87912..f922c4eb 100644 --- a/src/iptvsimple/utilities/StreamUtils.cpp +++ b/src/iptvsimple/utilities/StreamUtils.cpp @@ -20,17 +20,28 @@ using namespace iptvsimple; using namespace iptvsimple::data; using namespace iptvsimple::utilities; +namespace +{ +bool SplitUrlProtocolOpts(const std::string& streamURL, + std::string& url, + std::string& encodedProtocolOptions) +{ + size_t found = streamURL.find_first_of('|'); + if (found != std::string::npos) + { + // Headers found, split and url-encode them + url = streamURL.substr(0, found); + const std::string& protocolOptions = streamURL.substr(found + 1, streamURL.length()); + encodedProtocolOptions = StreamUtils::GetUrlEncodedProtocolOptions(protocolOptions); + return true; + } + return false; +} +} // unnamed namespace + void StreamUtils::SetAllStreamProperties(std::vector& properties, const iptvsimple::data::Channel& channel, const std::string& streamURL, bool isChannelURL, std::map& catchupProperties, std::shared_ptr& settings) { - // Check if the channel has explicitly set up the use of inputstream.adaptive, - // if so, the best behaviour for media services is: - // - Always add mimetype to prevent kodi core to make an HTTP HEADER requests - // this because in some cases services refuse this request and can also deny downloads - // - If requested by settings, always add the "user-agent" header to ISA properties - const bool isISAdaptiveSet = - channel.GetProperty(PVR_STREAM_PROPERTY_INPUTSTREAM) == INPUTSTREAM_ADAPTIVE; - - if (!isISAdaptiveSet && ChannelSpecifiesInputstream(channel)) + if (ChannelSpecifiesInputstream(channel)) { // Channel has an inputstream class set so we only set the stream URL properties.emplace_back(PVR_STREAM_PROPERTY_STREAMURL, streamURL); @@ -48,7 +59,7 @@ void StreamUtils::SetAllStreamProperties(std::vector