Skip to content

Commit

Permalink
Merge pull request #792 from phunkyfish/fix-media-metadata
Browse files Browse the repository at this point in the history
Fix media metadata
  • Loading branch information
phunkyfish authored Oct 8, 2023
2 parents 6437ad1 + 5d91c03 commit 9573291
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 32 deletions.
2 changes: 1 addition & 1 deletion pvr.iptvsimple/addon.xml.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon
id="pvr.iptvsimple"
version="21.4.0"
version="21.4.1"
name="IPTV Simple Client"
provider-name="nightik and Ross Nicholson">
<requires>@ADDON_DEPENDS@
Expand Down
5 changes: 5 additions & 0 deletions pvr.iptvsimple/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v21.4.1
- EPG entry selection criteria for timezone shift calculation works for Media as well as channels
- Fix being able to disable media from settings
- Fix group name in recording path being disabled in addon settings when media is not enabled

v21.4.0
- M3U format specifier to override realtime processing in Kodi PVR where the stream should not be treated like VOD/Media in the UI
- Revert the support of Async connect that was causing Connection Lost error messages for users of this add-on
Expand Down
3 changes: 3 additions & 0 deletions pvr.iptvsimple/resources/instance-settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,9 @@
<option label="30159">2</option> <!-- USE_GROUP_TITLE_IF_NO_PATH -->
</options>
</constraints>
<dependencies>
<dependency type="enable" setting="mediaEnabled" operator="is">true</dependency>
</dependencies>
<control type="spinner" format="integer" />
</setting>
<setting id="mediaForcePlaylist" type="boolean" parent="mediaEnabled" label="30160" help="30807">
Expand Down
30 changes: 19 additions & 11 deletions src/iptvsimple/Epg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void Epg::SetEPGMaxFutureDays(int epgMaxFutureDays)
m_epgMaxFutureDaysSeconds = DEFAULT_EPG_MAX_DAYS * 24 * 60 * 60;
}

bool Epg::LoadEPG(time_t start, time_t end)
bool Epg::LoadEPG(time_t epgWindowStart, time_t epgWindowEnd)
{
auto started = std::chrono::high_resolution_clock::now();
Logger::Log(LEVEL_DEBUG, "%s - EPG Load Start", __FUNCTION__);
Expand Down Expand Up @@ -125,7 +125,7 @@ bool Epg::LoadEPG(time_t start, time_t end)
if (!LoadChannelEpgs(rootElement))
return false;

LoadEpgEntries(rootElement, start, end);
LoadEpgEntries(rootElement, epgWindowStart, epgWindowEnd);

xmlDoc.reset();
}
Expand Down Expand Up @@ -283,7 +283,7 @@ bool Epg::LoadChannelEpgs(const xml_node& rootElement)
return true;
}

void Epg::LoadEpgEntries(const xml_node& rootElement, int start, int end)
void Epg::LoadEpgEntries(const xml_node& rootElement, int epgWindowStart, int epgWindowEnd)
{
int minShiftTime = m_epgTimeShift;
int maxShiftTime = m_epgTimeShift;
Expand All @@ -299,6 +299,14 @@ void Epg::LoadEpgEntries(const xml_node& rootElement, int start, int end)
if (channel.GetTvgShift() + m_epgTimeShift > maxShiftTime)
maxShiftTime = channel.GetTvgShift() + m_epgTimeShift;
}

for (const auto& mediaEntry : m_media.GetMediaEntryList())
{
if (mediaEntry.GetTvgShift() + m_epgTimeShift < minShiftTime)
minShiftTime = mediaEntry.GetTvgShift() + m_epgTimeShift;
if (mediaEntry.GetTvgShift() + m_epgTimeShift > maxShiftTime)
maxShiftTime = mediaEntry.GetTvgShift() + m_epgTimeShift;
}
}

ChannelEpg* channelEpg = nullptr;
Expand All @@ -317,7 +325,7 @@ void Epg::LoadEpgEntries(const xml_node& rootElement, int start, int end)
}

EpgEntry entry{m_settings};
if (entry.UpdateFrom(programmeNode, id, start, end, minShiftTime, maxShiftTime))
if (entry.UpdateFrom(programmeNode, id, epgWindowStart, epgWindowEnd, minShiftTime, maxShiftTime))
{
count++;

Expand Down Expand Up @@ -350,23 +358,23 @@ void Epg::ReloadEPG()
}
}

PVR_ERROR Epg::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::addon::PVREPGTagsResultSet& results)
PVR_ERROR Epg::GetEPGForChannel(int channelUid, time_t epgWindowStart, time_t epgWindowEnd, kodi::addon::PVREPGTagsResultSet& results)
{
for (const auto& myChannel : m_channels.GetChannelsList())
{
if (myChannel.GetUniqueId() != channelUid)
continue;

if (start > m_lastStart || end > m_lastEnd)
if (epgWindowStart > m_lastStart || epgWindowEnd > m_lastEnd)
{
// reload EPG for new time interval only
LoadEPG(start, end);
LoadEPG(epgWindowStart, epgWindowEnd);
{
MergeEpgDataIntoMedia();

// doesn't matter is epg loaded or not we shouldn't try to load it for same interval
m_lastStart = static_cast<int>(start);
m_lastEnd = static_cast<int>(end);
m_lastStart = static_cast<int>(epgWindowStart);
m_lastEnd = static_cast<int>(epgWindowEnd);
}
}

Expand All @@ -379,7 +387,7 @@ PVR_ERROR Epg::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::
for (auto& epgEntryPair : channelEpg->GetEpgEntries())
{
auto& epgEntry = epgEntryPair.second;
if ((epgEntry.GetEndTime() + shift) < start)
if ((epgEntry.GetEndTime() + shift) < epgWindowStart)
continue;

kodi::addon::PVREPGTag tag;
Expand All @@ -388,7 +396,7 @@ PVR_ERROR Epg::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::

results.Add(tag);

if ((epgEntry.GetStartTime() + shift) > end)
if ((epgEntry.GetStartTime() + shift) > epgWindowEnd)
break;
}

Expand Down
4 changes: 2 additions & 2 deletions src/iptvsimple/Epg.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace iptvsimple

bool Init(int epgMaxPastDays, int epgMaxFutureDays);

PVR_ERROR GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::addon::PVREPGTagsResultSet& results);
PVR_ERROR GetEPGForChannel(int channelUid, time_t epgWindowStart, time_t epgWindowEnd, kodi::addon::PVREPGTagsResultSet& results);
void SetEPGMaxPastDays(int epgMaxPastDays);
void SetEPGMaxFutureDays(int epgMaxFutureDays);
void Clear();
Expand All @@ -62,7 +62,7 @@ namespace iptvsimple
bool GetXMLTVFileWithRetries(std::string& data);
char* FillBufferFromXMLTVData(std::string& data, std::string& decompressedData);
bool LoadChannelEpgs(const pugi::xml_node& rootElement);
void LoadEpgEntries(const pugi::xml_node& rootElement, int start, int end);
void LoadEpgEntries(const pugi::xml_node& rootElement, int epgWindowStart, int epgWindowEnd);
bool LoadGenres();

void MergeEpgDataIntoMedia();
Expand Down
22 changes: 12 additions & 10 deletions src/iptvsimple/PlaylistLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,19 @@ bool PlaylistLoader::LoadPlayList()
}
else if (line[0] != '#')
{
Logger::Log(LEVEL_DEBUG, "%s - Adding channel '%s' with URL: '%s'", __FUNCTION__, tmpChannel.GetChannelName().c_str(), line.c_str());
Logger::Log(LEVEL_DEBUG, "%s - Adding channel or Media Entry '%s' with URL: '%s'", __FUNCTION__, tmpChannel.GetChannelName().c_str(), line.c_str());

if ((isRealTime || overrideRealTime || !m_settings->IsMediaEnabled() || !m_settings->ShowVodAsRecordings()) && !isMediaEntry)
if (m_settings->IsMediaEnabled() &&
(isMediaEntry || (m_settings->ShowVodAsRecordings() && !isRealTime)))
{
MediaEntry entry = tmpMediaEntry;
entry.UpdateFrom(tmpChannel);
entry.SetStreamURL(line);

if (!m_media.AddMediaEntry(entry, currentChannelGroupIdList, m_channelGroups, channelHadGroups))
Logger::Log(LEVEL_DEBUG, "%s - Counld not add media entry as an entry with the same gnenerated unique ID already exists", __func__);
}
else
{
// There are cases where we want the stream to be represetned as a channel with live streaming disabled
// to allow features such as passthrough to work. We don't want this to be VOD as then it would be treated like media.
Expand All @@ -230,15 +240,7 @@ bool PlaylistLoader::LoadPlayList()

if (!m_channels.AddChannel(channel, currentChannelGroupIdList, m_channelGroups, channelHadGroups))
Logger::Log(LEVEL_DEBUG, "%s - Not adding channel '%s' as only channels with groups are supported for %s channels per add-on settings", __func__, tmpChannel.GetChannelName().c_str(), channel.IsRadio() ? "radio" : "tv");
}
else // We have media
{
MediaEntry entry = tmpMediaEntry;
entry.UpdateFrom(tmpChannel);
entry.SetStreamURL(line);

if (!m_media.AddMediaEntry(entry, currentChannelGroupIdList, m_channelGroups, channelHadGroups))
Logger::Log(LEVEL_DEBUG, "%s - Counld not add media entry as an entry with the same gnenerated unique ID already exists", __func__);
}

tmpChannel.Reset();
Expand Down
23 changes: 16 additions & 7 deletions src/iptvsimple/data/EpgEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,31 +186,40 @@ int ParseStarRating(const std::string& starRatingString)
return static_cast<int>(std::round(starRating));
}

bool FirstRun(int start, int end)
{
return start == 0 && end == 0;
}

} // unnamed namespace

bool EpgEntry::UpdateFrom(const xml_node& programmeNode, const std::string& id,
int start, int end, int minShiftTime, int maxShiftTime)
int epgWindowsStart, int epgWindowsEnd, int minShiftTime, int maxShiftTime)
{
std::string strStart, strStop;
if (!GetAttributeValue(programmeNode, "start", strStart) || !GetAttributeValue(programmeNode, "stop", strStop))
return false;

long long tmpStart = ParseDateTime(strStart);
long long tmpEnd = ParseDateTime(strStop);
long long programmeStart = ParseDateTime(strStart);
long long programmeEnd = ParseDateTime(strStop);

GetAttributeValue(programmeNode, "catchup-id", m_catchupId);
m_catchupId = StringUtils::Trim(m_catchupId);

if ((tmpEnd + maxShiftTime < start) || (tmpStart + minShiftTime > end))
// Discard only if this is not a first run AND
// - The programme end time + the max timeshift is earlier than the EPG window start OR
// - The programme start time + the min timeshift is after than the EPG window end
// I.e. we discard any programme that does not start of finish during the EPG window
if (!FirstRun(epgWindowsStart, epgWindowsEnd) && ((programmeEnd + maxShiftTime < epgWindowsStart) || (programmeStart + minShiftTime > epgWindowsEnd)))
return false;

m_broadcastId = static_cast<int>(tmpStart);
m_broadcastId = static_cast<int>(programmeStart);
m_channelId = std::atoi(id.c_str());
m_genreType = 0;
m_genreSubType = 0;
m_plotOutline.clear();
m_startTime = static_cast<time_t>(tmpStart);
m_endTime = static_cast<time_t>(tmpEnd);
m_startTime = static_cast<time_t>(programmeStart);
m_endTime = static_cast<time_t>(programmeEnd);
m_year = 0;
m_starRating = 0;
m_episodeNumber = EPG_TAG_INVALID_SERIES_EPISODE;
Expand Down
2 changes: 1 addition & 1 deletion src/iptvsimple/data/EpgEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace iptvsimple

void UpdateTo(kodi::addon::PVREPGTag& left, int iChannelUid, int timeShift, const std::vector<EpgGenre>& genres);
bool UpdateFrom(const pugi::xml_node& programmeNode, const std::string& id,
int start, int end, int minShiftTime, int maxShiftTime);
int epgWindowsStart, int epgWindowsEnd, int minShiftTime, int maxShiftTime);

private:
bool SetEpgGenre(std::vector<EpgGenre> genreMappings);
Expand Down
3 changes: 3 additions & 0 deletions src/iptvsimple/data/MediaEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ void MediaEntry::Reset()
m_providerUniqueId = PVR_PROVIDER_INVALID_UID;
m_directory.clear();
m_sizeInBytes = 0;

m_tvgShift = 0;
}

void MediaEntry::UpdateFrom(iptvsimple::data::Channel channel)
Expand All @@ -66,6 +68,7 @@ void MediaEntry::UpdateFrom(iptvsimple::data::Channel channel)
m_iconPath = channel.GetIconPath();
m_tvgId = channel.GetTvgId();
m_tvgName = channel.GetTvgId();
m_tvgShift = channel.GetTvgShift();
m_startTime = std::time(nullptr);

m_providerUniqueId = channel.GetProviderUniqueId();
Expand Down
3 changes: 3 additions & 0 deletions src/iptvsimple/data/MediaEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ namespace iptvsimple
const std::string& GetM3UName() const { return m_m3uName; }
const std::string& GetTvgId() const { return m_tvgId; }
const std::string& GetTvgName() const { return m_tvgName; }
int GetTvgShift() const { return m_tvgShift; }
void SetTvgShift(int value) { m_tvgShift = value; }

const std::map<std::string, std::string>& GetProperties() const { return m_properties; }
void SetProperties(std::map<std::string, std::string>& value) { m_properties = value; }
Expand Down Expand Up @@ -106,6 +108,7 @@ namespace iptvsimple
std::string m_m3uName;
std::string m_tvgId;
std::string m_tvgName;
int m_tvgShift = 0;

// Props
std::map<std::string, std::string> m_properties;
Expand Down

0 comments on commit 9573291

Please sign in to comment.