From 395606626fb38340608ed34f25c9ddbb6aeb6c7a Mon Sep 17 00:00:00 2001 From: phunkyfish Date: Sat, 29 Jan 2022 18:24:13 +0000 Subject: [PATCH 1/7] Choose a suitable default stream type for default and append catchup modes --- src/iptvsimple/utilities/StreamUtils.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/iptvsimple/utilities/StreamUtils.cpp b/src/iptvsimple/utilities/StreamUtils.cpp index 9a8721bbc..1f0862f39 100644 --- a/src/iptvsimple/utilities/StreamUtils.cpp +++ b/src/iptvsimple/utilities/StreamUtils.cpp @@ -256,8 +256,10 @@ const StreamType StreamUtils::InspectStreamType(const std::string& url, const Ch return StreamType::SMOOTH_STREAMING; } - // If we can't inspect the stream type the only option left for shift mode is TS - if (channel.GetCatchupMode() == CatchupMode::SHIFT || + // If we can't inspect the stream type the only option left for default, append or shift mode is TS + if (channel.GetCatchupMode() == CatchupMode::DEFAULT || + channel.GetCatchupMode() == CatchupMode::APPEND || + channel.GetCatchupMode() == CatchupMode::SHIFT || channel.GetCatchupMode() == CatchupMode::TIMESHIFT) return StreamType::TS; From b498b1f2c654f2a4116ed598bbfe4ba88e823633 Mon Sep 17 00:00:00 2001 From: phunkyfish Date: Sun, 30 Jan 2022 11:54:21 +0000 Subject: [PATCH 2/7] Allow catchup tags in M3U header --- src/iptvsimple/PlaylistLoader.cpp | 27 ++++++++++++++++++++++++--- src/iptvsimple/PlaylistLoader.h | 9 +++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/iptvsimple/PlaylistLoader.cpp b/src/iptvsimple/PlaylistLoader.cpp index b34511989..b15a8c4ef 100644 --- a/src/iptvsimple/PlaylistLoader.cpp +++ b/src/iptvsimple/PlaylistLoader.cpp @@ -104,10 +104,22 @@ bool PlaylistLoader::LoadPlayList() catchupCorrectionSecs = static_cast(catchupCorrectionDecimal * 3600.0); } - std::string strXeevCatchup = ReadMarkerValue(line, CATCHUP); - if (strXeevCatchup == "xc") + // + // If there are catchup values in the M3U header we read them to be used as defaults later on + // + m_m3uHeaderStrings.m_catchup = ReadMarkerValue(line, CATCHUP); + // There is some xeev specific functionality if specificed in the header + if (m_m3uHeaderStrings.m_catchup == "xc") xeevCatchup = true; - + // Some providers use a 'catchup-type' tag instead of 'catchup' + if (m_m3uHeaderStrings.m_catchup.empty()) + m_m3uHeaderStrings.m_catchup = ReadMarkerValue(line, CATCHUP_TYPE); + m_m3uHeaderStrings.m_catchupDays = ReadMarkerValue(line, CATCHUP_DAYS); + m_m3uHeaderStrings.m_catchupSource = ReadMarkerValue(line, CATCHUP_SOURCE); + + // + // Read either of the M3U header based EPG xmltv urls + // std::string tvgUrl = ReadMarkerValue(line, TVG_URL_MARKER); if (tvgUrl.empty()) tvgUrl = ReadMarkerValue(line, TVG_URL_OTHER_MARKER); @@ -280,6 +292,9 @@ std::string PlaylistLoader::ParseIntoChannel(const std::string& line, Channel& c // Some providers use a 'catchup-type' tag instead of 'catchup' if (strCatchup.empty()) strCatchup = ReadMarkerValue(infoLine, CATCHUP_TYPE); + // If we still don't have a value use the header supplied value if there is one + if (strCatchup.empty() && !m_m3uHeaderStrings.m_catchup.empty()) + strCatchup = m_m3uHeaderStrings.m_catchup; if (strTvgId.empty()) strTvgId = ReadMarkerValue(infoLine, TVG_INFO_ID_MARKER_UC); @@ -311,6 +326,9 @@ std::string PlaylistLoader::ParseIntoChannel(const std::string& line, Channel& c channel.SetTvgId(strTvgId); channel.SetTvgName(strTvgName); channel.SetCatchupSource(strCatchupSource); + // If we still don't have a value use the header supplied value if there is one + if (strCatchupSource.empty() && !m_m3uHeaderStrings.m_catchupSource.empty()) + strCatchupSource = m_m3uHeaderStrings.m_catchupSource; channel.SetTvgShift(static_cast(tvgShiftDecimal * 3600.0)); channel.SetRadio(isRadio); if (Settings::GetInstance().GetLogoPathType() == PathType::LOCAL_PATH && Settings::GetInstance().UseLocalLogosOnlyIgnoreM3U()) @@ -359,6 +377,9 @@ std::string PlaylistLoader::ParseIntoChannel(const std::string& line, Channel& c if (!strCatchupDays.empty()) channel.SetCatchupDays(atoi(strCatchupDays.c_str())); + // If we still don't have a value use the header supplied value if there is one + else if (!m_m3uHeaderStrings.m_catchupSource.empty()) + channel.SetCatchupDays(atoi(m_m3uHeaderStrings.m_catchupDays.c_str())); else if (channel.GetCatchupMode() == CatchupMode::VOD) channel.SetCatchupDays(IGNORE_CATCHUP_DAYS); else if (siptvTimeshiftDays > 0) diff --git a/src/iptvsimple/PlaylistLoader.h b/src/iptvsimple/PlaylistLoader.h index 1904924ab..e9ac1a600 100644 --- a/src/iptvsimple/PlaylistLoader.h +++ b/src/iptvsimple/PlaylistLoader.h @@ -53,6 +53,13 @@ namespace iptvsimple class PlaylistLoader { + struct M3UHeaderStrings { + // members will be public without `private:` keyword + std::string m_catchup; + std::string m_catchupDays; + std::string m_catchupSource; + }; + public: PlaylistLoader(kodi::addon::CInstancePVRClient* client, iptvsimple::Channels& channels, iptvsimple::ChannelGroups& channelGroups, iptvsimple::Providers& providers, @@ -78,5 +85,7 @@ namespace iptvsimple iptvsimple::Channels& m_channels; iptvsimple::Media& m_media; kodi::addon::CInstancePVRClient* m_client; + + M3UHeaderStrings m_m3uHeaderStrings; }; } //namespace iptvsimple From ea2e5e729e73bae71e42421d8bae08957af0a790 Mon Sep 17 00:00:00 2001 From: phunkyfish Date: Sun, 30 Jan 2022 13:07:13 +0000 Subject: [PATCH 3/7] Update flussonic catchup type strings --- src/iptvsimple/PlaylistLoader.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/iptvsimple/PlaylistLoader.cpp b/src/iptvsimple/PlaylistLoader.cpp index b15a8c4ef..c0f405671 100644 --- a/src/iptvsimple/PlaylistLoader.cpp +++ b/src/iptvsimple/PlaylistLoader.cpp @@ -345,8 +345,9 @@ std::string PlaylistLoader::ParseIntoChannel(const std::string& line, Channel& c if (StringUtils::EqualsNoCase(strCatchup, "default") || StringUtils::EqualsNoCase(strCatchup, "append") || StringUtils::EqualsNoCase(strCatchup, "shift") || StringUtils::EqualsNoCase(strCatchup, "flussonic") || - StringUtils::EqualsNoCase(strCatchup, "flussonic-ts") || StringUtils::EqualsNoCase(strCatchup, "fs") || - StringUtils::EqualsNoCase(strCatchup, "xc") || StringUtils::EqualsNoCase(strCatchup, "vod")) + StringUtils::EqualsNoCase(strCatchup, "flussonic-hls") || StringUtils::EqualsNoCase(strCatchup, "flussonic-ts") || + StringUtils::EqualsNoCase(strCatchup, "fs") || StringUtils::EqualsNoCase(strCatchup, "xc") || + StringUtils::EqualsNoCase(strCatchup, "vod")) channel.SetHasCatchup(true); if (StringUtils::EqualsNoCase(strCatchup, "default")) @@ -355,13 +356,17 @@ std::string PlaylistLoader::ParseIntoChannel(const std::string& line, Channel& c channel.SetCatchupMode(CatchupMode::APPEND); else if (StringUtils::EqualsNoCase(strCatchup, "shift")) channel.SetCatchupMode(CatchupMode::SHIFT); - else if (StringUtils::EqualsNoCase(strCatchup, "flussonic") || StringUtils::EqualsNoCase(strCatchup, "flussonic-ts") || StringUtils::EqualsNoCase(strCatchup, "fs")) + else if (StringUtils::EqualsNoCase(strCatchup, "flussonic") || StringUtils::EqualsNoCase(strCatchup, "flussonic-hls") || + StringUtils::EqualsNoCase(strCatchup, "flussonic-ts") || StringUtils::EqualsNoCase(strCatchup, "fs")) channel.SetCatchupMode(CatchupMode::FLUSSONIC); else if (StringUtils::EqualsNoCase(strCatchup, "xc")) channel.SetCatchupMode(CatchupMode::XTREAM_CODES); else if (StringUtils::EqualsNoCase(strCatchup, "vod")) channel.SetCatchupMode(CatchupMode::VOD); + if (StringUtils::EqualsNoCase(strCatchup, "flussonic-ts") || StringUtils::EqualsNoCase(strCatchup, "fs")) + channel.SetCatchupTSStream(true); + if (!channel.HasCatchup() && xeevCatchup && (StringUtils::StartsWith(channelName, "* ") || StringUtils::StartsWith(channelName, "[+] "))) { channel.SetHasCatchup(true); From ebbf0e09c6f10758cf9e95965d733ba014cd4518 Mon Sep 17 00:00:00 2001 From: phunkyfish Date: Sun, 30 Jan 2022 14:50:06 +0000 Subject: [PATCH 4/7] For flussonic catchup add support for generic stream types (where any dir name is used after channel id) --- src/iptvsimple/data/Channel.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/iptvsimple/data/Channel.cpp b/src/iptvsimple/data/Channel.cpp index 7404548c2..bf844f081 100644 --- a/src/iptvsimple/data/Channel.cpp +++ b/src/iptvsimple/data/Channel.cpp @@ -435,12 +435,15 @@ bool Channel::GenerateFlussonicCatchupSource(const std::string& url) // catchup: http://list.tv:8888/325/timeshift_rel-{offset:1}.m3u8?token=secret // stream: http://list.tv:8888/325/mono.m3u8?token=secret // catchup: http://list.tv:8888/325/mono-timeshift_rel-{offset:1}.m3u8?token=secret + // stream: http://list.tv:8888/325/live?token=my_token + // catchup: http://list.tv:8888/325/{utc}.ts?token=my_token static std::regex fsRegex("^(http[s]?://[^/]+)/(.*)/([^/]*)(mpegts|\\.m3u8)(\\?.+=.+)?$"); std::smatch matches; if (std::regex_match(url, matches, fsRegex)) { + // This is path for well defined stream naming if (matches.size() == 6) { const std::string fsHost = matches[1].str(); @@ -465,6 +468,31 @@ bool Channel::GenerateFlussonicCatchupSource(const std::string& url) return true; } } + else + { + // Flussonic servers will return a stream with any directory name after the channel id + // so we handle this case separately + static std::regex genericRegex("^(http[s]?://[^/]+)/(.*)/([^\\?]*)(\\?.+=.+)?$"); + std::smatch genericMmatches; + + if (std::regex_match(url, genericMmatches, genericRegex)) + { + if (genericMmatches.size() == 5) + { + const std::string fsHost = genericMmatches[1].str(); + const std::string fsChannelId = genericMmatches[2].str(); + const std::string fsStreamType = genericMmatches[3].str(); + const std::string fsUrlAppend = genericMmatches[4].str(); + + if (m_isCatchupTSStream) // the catchup type was "flussonic-ts" or "fs" + m_catchupSource = fsHost + "/" + fsChannelId + "/timeshift_abs-${start}.ts" + fsUrlAppend; + else // the catchup type was "flussonic" or "flussonic-hls" + m_catchupSource = fsHost + "/" + fsChannelId + "/timeshift_rel-{offset:1}.m3u8" + fsUrlAppend; + + return true; + } + } + } return false; } From b2a58409062fdb85a96be08f9939712392b5920f Mon Sep 17 00:00:00 2001 From: phunkyfish Date: Sun, 30 Jan 2022 15:14:07 +0000 Subject: [PATCH 5/7] Support alternative tag name for channel number --- src/iptvsimple/PlaylistLoader.cpp | 4 ++++ src/iptvsimple/PlaylistLoader.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/iptvsimple/PlaylistLoader.cpp b/src/iptvsimple/PlaylistLoader.cpp index c0f405671..480112a7b 100644 --- a/src/iptvsimple/PlaylistLoader.cpp +++ b/src/iptvsimple/PlaylistLoader.cpp @@ -306,6 +306,10 @@ std::string PlaylistLoader::ParseIntoChannel(const std::string& line, Channel& c strTvgId.append(buff); } + // If don't have a channel number try another format + if (strChnlNo.empty()) + ReadMarkerValue(infoLine, CHANNEL_NUMBER_MARKER); + if (!strChnlNo.empty() && !Settings::GetInstance().NumberChannelsByM3uOrderOnly()) { size_t found = strChnlNo.find('.'); diff --git a/src/iptvsimple/PlaylistLoader.h b/src/iptvsimple/PlaylistLoader.h index e9ac1a600..8b18ad29d 100644 --- a/src/iptvsimple/PlaylistLoader.h +++ b/src/iptvsimple/PlaylistLoader.h @@ -29,6 +29,7 @@ namespace iptvsimple static const std::string TVG_INFO_LOGO_MARKER = "tvg-logo="; static const std::string TVG_INFO_SHIFT_MARKER = "tvg-shift="; static const std::string TVG_INFO_CHNO_MARKER = "tvg-chno="; + static const std::string CHANNEL_NUMBER_MARKER = "ch-number="; static const std::string TVG_INFO_REC = "tvg-rec="; // some providers use 'tvg-rec' instead of 'catchup-days' static const std::string GROUP_NAME_MARKER = "group-title="; static const std::string CATCHUP = "catchup="; @@ -58,7 +59,7 @@ namespace iptvsimple std::string m_catchup; std::string m_catchupDays; std::string m_catchupSource; - }; + }; public: PlaylistLoader(kodi::addon::CInstancePVRClient* client, iptvsimple::Channels& channels, From 48b30d3ae8ae319c5d7ef849b94ded262638a7a6 Mon Sep 17 00:00:00 2001 From: phunkyfish Date: Sun, 30 Jan 2022 17:21:40 +0000 Subject: [PATCH 6/7] Fix incorrect provider mappings file path --- pvr.iptvsimple/resources/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvr.iptvsimple/resources/settings.xml b/pvr.iptvsimple/resources/settings.xml index af39bd896..e31c1eb1e 100644 --- a/pvr.iptvsimple/resources/settings.xml +++ b/pvr.iptvsimple/resources/settings.xml @@ -122,7 +122,7 @@ 2 - special://userdata/addon_data/pvr.iptvsimple/providers/providersMappings.xml + special://userdata/addon_data/pvr.iptvsimple/providers/providerMappings.xml false false From a1a5f0fe6ab3ac59fa2f77f2a9822e9584c28c2e Mon Sep 17 00:00:00 2001 From: phunkyfish Date: Sat, 29 Jan 2022 18:25:47 +0000 Subject: [PATCH 7/7] changelog and version - 20.3.0 --- pvr.iptvsimple/addon.xml.in | 2 +- pvr.iptvsimple/changelog.txt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pvr.iptvsimple/addon.xml.in b/pvr.iptvsimple/addon.xml.in index 98e3c8218..42bde4848 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 dd2037e98..528c2c6eb 100644 --- a/pvr.iptvsimple/changelog.txt +++ b/pvr.iptvsimple/changelog.txt @@ -1,3 +1,11 @@ +v20.3.0 +- Choose a suitable default stream type for default and append catchup modes +- Allow catchup tags in M3U header +- Update flussonic catchup type strings +- For flussonic catchup add support for generic stream types (where any dir name is used after channel id) +- Support alternative tag name for channel number +- Fix incorrect provider mappings file path + v20.2.1 - Remove redundant PVR from addon name