Skip to content

Commit

Permalink
Omega final changes (#266)
Browse files Browse the repository at this point in the history
* Timeshift change

Start timeshift in real time mode.  Low bit radio was taking to long to buffer.

* Series and episode clean up

Remove duplicated series information from recordings, timer and EPG.  Parse episode display information from the description.
  • Loading branch information
emveepee authored Aug 11, 2024
1 parent c0649cc commit 7b372f6
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 24 deletions.
2 changes: 1 addition & 1 deletion pvr.nextpvr/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.nextpvr"
version="21.1.1"
version="21.2.0"
name="NextPVR PVR Client"
provider-name="Graeme Blackley">
<requires>@ADDON_DEPENDS@
Expand Down
5 changes: 5 additions & 0 deletions pvr.nextpvr/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v21.2.0
- Start timeshift in realtime for radio playback
- Add support for episode and episode part parsing
- Clean up duplicated S/E information sent from NextPVR in the subtitle when no subtitle is present.

v21.1.1
- Translations updates from Weblate
- af_za, am_et, ar_sa, ast_es, az_az, be_by, bg_bg, bs_ba, ca_es, cs_cz, cy_gb, da_dk, de_de, el_gr, en_au, en_nz, en_us, eo, es_ar, es_es, es_mx, et_ee, eu_es, fa_af, fa_ir, fi_fi, fo_fo, fr_ca, fr_fr, gl_es, he_il, hi_in, hr_hr, hu_hu, hy_am, id_id, is_is, it_it, ja_jp, ko_kr, lt_lt, lv_lv, mi, mk_mk, ml_in, mn_mn, ms_my, mt_mt, my_mm, nb_no, nl_nl, pl_pl, pt_br, pt_pt, ro_ro, ru_ru, si_lk, sk_sk, sl_si, sq_al, sr_rs, sr_rs@latin, sv_se, szl, ta_in, te_in, tg_tj, th_th, tr_tr, uk_ua, uz_uz, vi_vn, zh_cn, zh_tw
Expand Down
63 changes: 56 additions & 7 deletions src/EPG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ PVR_ERROR EPG::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::
}
}

broadcast.SetYear(XMLUtils::GetIntValue(pListingNode, "year"));

std::string startTime;
std::string endTime;
XMLUtils::GetString(pListingNode, "start", startTime);
Expand All @@ -80,7 +78,6 @@ PVR_ERROR EPG::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::
const std::string oidLookup(endTime + ":" + std::to_string(channelUid));

broadcast.SetTitle(title);
broadcast.SetEpisodeName(subtitle);
broadcast.SetUniqueChannelId(channelUid);
broadcast.SetStartTime(stol(startTime));
broadcast.SetUniqueBroadcastId(stoi(endTime));
Expand Down Expand Up @@ -132,13 +129,65 @@ PVR_ERROR EPG::GetEPGForChannel(int channelUid, time_t start, time_t end, kodi::
}

}
broadcast.SetSeriesNumber(XMLUtils::GetIntValue(pListingNode, "season", EPG_TAG_INVALID_SERIES_EPISODE));
broadcast.SetEpisodeNumber(XMLUtils::GetIntValue(pListingNode, "episode", EPG_TAG_INVALID_SERIES_EPISODE));

int season{ EPG_TAG_INVALID_SERIES_EPISODE };
int episode = {EPG_TAG_INVALID_SERIES_EPISODE};
XMLUtils::GetInt(pListingNode, "season", season);
XMLUtils::GetInt(pListingNode, "episode", episode);
broadcast.SetEpisodeNumber(episode);
broadcast.SetEpisodePartNumber(EPG_TAG_INVALID_SERIES_EPISODE);
// Backend could send epidode only as S00 and parts are not support
if (season <= 0 || episode == EPG_TAG_INVALID_SERIES_EPISODE)
{
std::regex base_regex("^.*\\([eE][pP](\\d+)(?:/?(\\d+))?\\)");
std::smatch base_match;
if (std::regex_search(description, base_match, base_regex))
{
broadcast.SetEpisodeNumber(std::atoi(base_match[1].str().c_str()));
if (base_match[2].matched)
broadcast.SetEpisodePartNumber(std::atoi(base_match[2].str().c_str()));
}
else if (std::regex_search(description, base_match, std::regex("^([1-9]\\d*)/([1-9]\\d*)\\.")))
{
broadcast.SetEpisodeNumber(std::atoi(base_match[1].str().c_str()));
broadcast.SetEpisodePartNumber(std::atoi(base_match[2].str().c_str()));
}
}
if (season != EPG_TAG_INVALID_SERIES_EPISODE)
{
// clear out NextPVR formatted data, Kodi supports S/E display
if (subtitle == kodi::tools::StringUtils::Format("S%02dE%02d", season, episode))
{
subtitle.clear();
}
if (season == 0)
season = EPG_TAG_INVALID_SERIES_EPISODE;
}
broadcast.SetSeriesNumber(season);
broadcast.SetEpisodeName(subtitle);

int year{-1};
if (XMLUtils::GetInt(pListingNode, "year", year))
{
broadcast.SetYear(year);
}

std::string original;
XMLUtils::GetString(pListingNode, "original", original);
broadcast.SetFirstAired(original);
if (XMLUtils::GetString(pListingNode, "original", original))
{
if (broadcast.GetGenreType() == 16 && broadcast.GetGenreSubType() == 0 && year == -1 && original.length() > 4)
{
const std::string originalYear = kodi::tools::StringUtils::Mid(original, 0, 4);
year = atoi(originalYear.c_str());
if (year != 0)
broadcast.SetYear(year);
}
else
{
broadcast.SetFirstAired(original);
}
}


bool firstrun;
if (XMLUtils::GetBoolean(pListingNode, "firstrun", firstrun))
Expand Down
47 changes: 31 additions & 16 deletions src/Recordings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,20 +323,17 @@ bool Recordings::UpdatePvrRecording(const tinyxml2::XMLNode* pRecordingNode, kod

tag.SetSeriesNumber(PVR_RECORDING_INVALID_SERIES_EPISODE);
tag.SetEpisodeNumber(PVR_RECORDING_INVALID_SERIES_EPISODE);

if (XMLUtils::GetString(pRecordingNode, "subtitle", buffer))
if (ParseNextPVRSubtitle(pRecordingNode, tag))
{
if (ParseNextPVRSubtitle(pRecordingNode, tag))
if (m_settings->m_separateSeasons && multipleSeasons && tag.GetSeriesNumber() != PVR_RECORDING_INVALID_SERIES_EPISODE)
{
if (m_settings->m_separateSeasons && multipleSeasons && tag.GetSeriesNumber() != PVR_RECORDING_INVALID_SERIES_EPISODE)
{
if (status != "Failed")
tag.SetDirectory(kodi::tools::StringUtils::Format("/%s/%s %d", tag.GetTitle().c_str(), kodi::addon::GetLocalizedString(20373).c_str(), tag.GetSeriesNumber()));
else
tag.SetDirectory(kodi::tools::StringUtils::Format("/%s/%s/%s %d", kodi::addon::GetLocalizedString(30166).c_str(),tag.GetTitle().c_str(), kodi::addon::GetLocalizedString(20373).c_str(), tag.GetSeriesNumber()));
}
if (status != "Failed")
tag.SetDirectory(kodi::tools::StringUtils::Format("/%s/%s %d", tag.GetTitle().c_str(), kodi::addon::GetLocalizedString(20373).c_str(), tag.GetSeriesNumber()));
else
tag.SetDirectory(kodi::tools::StringUtils::Format("/%s/%s/%s %d", kodi::addon::GetLocalizedString(30166).c_str(),tag.GetTitle().c_str(), kodi::addon::GetLocalizedString(20373).c_str(), tag.GetSeriesNumber()));
}
}

tag.SetYear(XMLUtils::GetIntValue(pRecordingNode, "year"));

std::string original;
Expand Down Expand Up @@ -473,24 +470,27 @@ bool Recordings::ParseNextPVRSubtitle(const tinyxml2::XMLNode *pRecordingNode, k
bool hasSeasonEpisode = false;
if (XMLUtils::GetString(pRecordingNode, "subtitle", buffer))
{
std::regex base_regex("S(\\d{2,4})E(\\d+) - ?(.+)?");
std::regex base_regex("S(\\d{2,4})E(\\d+)(?: - ?(.+)$)?");
std::smatch base_match;
// note NextPVR does not support S0 for specials
if (std::regex_match(buffer, base_match, base_regex))
if (std::regex_search(buffer, base_match, base_regex))
{
if (base_match.size() == 3 || base_match.size() == 4)
{

std::ssub_match base_sub_match = base_match[1];
tag.SetSeriesNumber(std::stoi(base_sub_match.str()));
int season = std::stoi(base_sub_match.str());
if (season != 0)
{
tag.SetSeriesNumber(season);
hasSeasonEpisode = true;
}
base_sub_match = base_match[2];
tag.SetEpisodeNumber(std::stoi(base_sub_match.str()));
if (base_match.size() == 4)
if (base_match[3].matched)
{
base_sub_match = base_match[3];
tag.SetEpisodeName(base_sub_match.str());
}
hasSeasonEpisode = true;
}
}
else
Expand Down Expand Up @@ -518,6 +518,21 @@ bool Recordings::ParseNextPVRSubtitle(const tinyxml2::XMLNode *pRecordingNode, k
}
}
}
const std::string plot = tag.GetPlot();
if (tag.GetEpisodeNumber() == PVR_RECORDING_INVALID_SERIES_EPISODE && !plot.empty());
{
// Kodi doesn't support episode parts on recordings
std::regex base_regex("^.*\\([eE][pP](\\d+)(?:/?(\\d+))?\\)");
std::smatch base_match;
if (std::regex_search(plot, base_match, base_regex))
{
tag.SetEpisodeNumber(std::atoi(base_match[1].str().c_str()));
}
else if (std::regex_search(plot, base_match, std::regex("^([1-9]\\d*)/([1-9]\\d*)\\.")))
{
tag.SetEpisodeNumber(std::atoi(base_match[1].str().c_str()));
}
}
}
return hasSeasonEpisode;
}
Expand Down
5 changes: 5 additions & 0 deletions src/buffers/ClientTimeshift.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,10 @@ namespace timeshift {
}
virtual PVR_ERROR GetStreamTimes(kodi::addon::PVRStreamTimes& times) override;

virtual bool IsRealTimeStream() const override
{
return time(nullptr) - m_streamStart < 10 + m_prebuffer;
}

};
}

0 comments on commit 7b372f6

Please sign in to comment.