Skip to content

Commit

Permalink
Merge pull request #779 from phunkyfish/disable-async-and-realtime-omega
Browse files Browse the repository at this point in the history
Revert Async Connect and allow disabling of live stream using M3U specifier - Omega
  • Loading branch information
phunkyfish authored Jul 27, 2023
2 parents 7a4c7bc + e369805 commit 6437ad1
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 19 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ http://path-to-stream/live/channel-z.ts
- `media`: Specifies that this entry is a media entry by setting the values true `true`. Same as setting `#EXT-X-PLAYLIST-TYPE` to VOD.
- `media-dir`: An optional directory path which should specifiy where in the hierarchy this media entry should be represented. The path separator is `/`.
- `media-size`: An optional size of the media entry in bytes. Note: this is not usually available for VOD libraries.
- `realtime`: Live streams in PVR disable features such as passthrough by default. Set this item to "false" to bypass this behaviour if the stream should not be treated like VOD/Media in the UI.
- `#EXTGRP`: A semi-colon separted list of channel groups that this channel belongs to.
- `#KODIPROP`: A single property in the format `key=value` that can be passed to Kodi. Multiple can be passed each on a separate line.
- `#EXTVLCOPT`: A single property in the format `key=value` that can be passed to Kodi. Multiple can be passed each on a separate line. Note that if either a `http-user-agent` or a `http-referrer` property is found it will added to the URL as a HTTP header as `user-agent` or `referrer` respectively if not already provided in the URL. These two fields specifically will be dropped as properties whether or not they are added as header values. They will be added in the same format as the `URL` below.
Expand Down
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.3.1"
version="21.4.0"
name="IPTV Simple Client"
provider-name="nightik and Ross Nicholson">
<requires>@ADDON_DEPENDS@
Expand Down
4 changes: 4 additions & 0 deletions pvr.iptvsimple/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
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

v21.3.1
- Remove empty media groups before sending to Kodi PVR

Expand Down
10 changes: 1 addition & 9 deletions src/IptvSimple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ bool IptvSimple::Initialise()
{
std::lock_guard<std::mutex> lock(m_mutex);

ConnectionStateChange("", PVR_CONNECTION_STATE_CONNECTING, "");

m_channels.Init();
m_channelGroups.Init();
m_providers.Init();
Expand All @@ -45,11 +43,6 @@ bool IptvSimple::Initialise()
{
m_channels.ChannelsLoadFailed();
m_channelGroups.ChannelGroupsLoadFailed();
ConnectionStateChange("", PVR_CONNECTION_STATE_DISCONNECTED, "");
}
else
{
ConnectionStateChange("", PVR_CONNECTION_STATE_CONNECTED, "");
}
m_epg.Init(EpgMaxPastDays(), EpgMaxFutureDays());

Expand Down Expand Up @@ -123,8 +116,7 @@ void IptvSimple::Process()
std::this_thread::sleep_for(std::chrono::milliseconds(1000));

m_settings->ReloadAddonInstanceSettings();
if (m_playlistLoader.ReloadPlayList())
ConnectionStateChange("", PVR_CONNECTION_STATE_CONNECTED, "");
m_playlistLoader.ReloadPlayList();
m_epg.ReloadEPG(); // Reloading EPG also updates media

m_reloadChannelsGroupsAndEPG = false;
Expand Down
45 changes: 37 additions & 8 deletions src/iptvsimple/PlaylistLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,33 @@ bool PlaylistLoader::Init()
return true;
}

namespace {

bool GetOverrideRealTime(std::string& line)
{
size_t realtimeIndex = line.find(REALTIME_OVERRIDE);
if (realtimeIndex != std::string::npos)
{
size_t startValueIndex = realtimeIndex + REALTIME_OVERRIDE.length();
size_t endQuoteIndex = line.find('"', startValueIndex);
if (endQuoteIndex != std::string::npos)
{
size_t valueLength = endQuoteIndex - startValueIndex;
std::string value = line.substr(startValueIndex, valueLength);
StringUtils::ToLower(value);
// The only value that matters is if the 'realtime' specifier is 'false'
// that means we want to override the realtime value but not treat the stream
// like media/VOD in the UI
// It's a bit confusing, but hey, that's Kodi for you ;)
return value == "false";
}
}

return false;
}

}

bool PlaylistLoader::LoadPlayList()
{
auto started = std::chrono::high_resolution_clock::now();
Expand All @@ -64,6 +91,7 @@ bool PlaylistLoader::LoadPlayList()
/* load channels */
bool isFirstLine = true;
bool isRealTime = true;
bool overrideRealTime = false;
bool isMediaEntry = false;
int epgTimeShift = 0;
int catchupCorrectionSecs = m_settings->GetCatchupCorrectionSecs();
Expand Down Expand Up @@ -149,6 +177,8 @@ bool PlaylistLoader::LoadPlayList()
line.find(MEDIA_SIZE) != std::string::npos ||
m_settings->MediaForcePlaylist();

overrideRealTime = GetOverrideRealTime(line);

const std::string groupNamesListString = ParseIntoChannel(line, tmpChannel, tmpMediaEntry, currentChannelGroupIdList, epgTimeShift, catchupCorrectionSecs, xeevCatchup);

if (!groupNamesListString.empty())
Expand Down Expand Up @@ -187,9 +217,12 @@ bool PlaylistLoader::LoadPlayList()
{
Logger::Log(LEVEL_DEBUG, "%s - Adding channel '%s' with URL: '%s'", __FUNCTION__, tmpChannel.GetChannelName().c_str(), line.c_str());

if ((isRealTime || !m_settings->IsMediaEnabled() || !m_settings->ShowVodAsRecordings()) && !isMediaEntry)
if ((isRealTime || overrideRealTime || !m_settings->IsMediaEnabled() || !m_settings->ShowVodAsRecordings()) && !isMediaEntry)
{
tmpChannel.AddProperty(PVR_STREAM_PROPERTY_ISREALTIMESTREAM, "true");
// 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.
if (!overrideRealTime)
tmpChannel.AddProperty(PVR_STREAM_PROPERTY_ISREALTIMESTREAM, "true");

Channel channel = tmpChannel;
channel.SetStreamURL(line);
Expand All @@ -206,12 +239,12 @@ bool PlaylistLoader::LoadPlayList()

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();
tmpMediaEntry.Reset();
isRealTime = true;
overrideRealTime = false;
isMediaEntry = false;
channelHadGroups = false;
}
Expand Down Expand Up @@ -535,7 +568,7 @@ void PlaylistLoader::ParseSinglePropertyIntoChannel(const std::string& line, Cha
}
}

bool PlaylistLoader::ReloadPlayList()
void PlaylistLoader::ReloadPlayList()
{
m_m3uLocation = m_settings->GetM3ULocation();

Expand All @@ -550,15 +583,11 @@ bool PlaylistLoader::ReloadPlayList()
m_client->TriggerChannelGroupsUpdate();
m_client->TriggerProvidersUpdate();
m_client->TriggerRecordingUpdate();

return true;
}
else
{
m_channels.ChannelsLoadFailed();
m_channelGroups.ChannelGroupsLoadFailed();

return false;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/iptvsimple/PlaylistLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace iptvsimple
static const std::string MEDIA = "media=";
static const std::string MEDIA_DIR = "media-dir=";
static const std::string MEDIA_SIZE = "media-size=";
static const std::string REALTIME_OVERRIDE = "realtime=\"";
static const std::string KODIPROP_MARKER = "#KODIPROP:";
static const std::string EXTVLCOPT_MARKER = "#EXTVLCOPT:";
static const std::string EXTVLCOPT_DASH_MARKER = "#EXTVLCOPT--";
Expand All @@ -71,7 +72,7 @@ namespace iptvsimple
bool Init();

bool LoadPlayList();
bool ReloadPlayList();
void ReloadPlayList();

private:
static std::string ReadMarkerValue(const std::string& line, const std::string& markerName);
Expand Down

0 comments on commit 6437ad1

Please sign in to comment.