Skip to content

Commit 6437ad1

Browse files
authored
Merge pull request #779 from phunkyfish/disable-async-and-realtime-omega
Revert Async Connect and allow disabling of live stream using M3U specifier - Omega
2 parents 7a4c7bc + e369805 commit 6437ad1

File tree

6 files changed

+46
-19
lines changed

6 files changed

+46
-19
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ http://path-to-stream/live/channel-z.ts
520520
- `media`: Specifies that this entry is a media entry by setting the values true `true`. Same as setting `#EXT-X-PLAYLIST-TYPE` to VOD.
521521
- `media-dir`: An optional directory path which should specifiy where in the hierarchy this media entry should be represented. The path separator is `/`.
522522
- `media-size`: An optional size of the media entry in bytes. Note: this is not usually available for VOD libraries.
523+
- `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.
523524
- `#EXTGRP`: A semi-colon separted list of channel groups that this channel belongs to.
524525
- `#KODIPROP`: A single property in the format `key=value` that can be passed to Kodi. Multiple can be passed each on a separate line.
525526
- `#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.

pvr.iptvsimple/addon.xml.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<addon
33
id="pvr.iptvsimple"
4-
version="21.3.1"
4+
version="21.4.0"
55
name="IPTV Simple Client"
66
provider-name="nightik and Ross Nicholson">
77
<requires>@ADDON_DEPENDS@

pvr.iptvsimple/changelog.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
v21.4.0
2+
- M3U format specifier to override realtime processing in Kodi PVR where the stream should not be treated like VOD/Media in the UI
3+
- Revert the support of Async connect that was causing Connection Lost error messages for users of this add-on
4+
15
v21.3.1
26
- Remove empty media groups before sending to Kodi PVR
37

src/IptvSimple.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ bool IptvSimple::Initialise()
3535
{
3636
std::lock_guard<std::mutex> lock(m_mutex);
3737

38-
ConnectionStateChange("", PVR_CONNECTION_STATE_CONNECTING, "");
39-
4038
m_channels.Init();
4139
m_channelGroups.Init();
4240
m_providers.Init();
@@ -45,11 +43,6 @@ bool IptvSimple::Initialise()
4543
{
4644
m_channels.ChannelsLoadFailed();
4745
m_channelGroups.ChannelGroupsLoadFailed();
48-
ConnectionStateChange("", PVR_CONNECTION_STATE_DISCONNECTED, "");
49-
}
50-
else
51-
{
52-
ConnectionStateChange("", PVR_CONNECTION_STATE_CONNECTED, "");
5346
}
5447
m_epg.Init(EpgMaxPastDays(), EpgMaxFutureDays());
5548

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

125118
m_settings->ReloadAddonInstanceSettings();
126-
if (m_playlistLoader.ReloadPlayList())
127-
ConnectionStateChange("", PVR_CONNECTION_STATE_CONNECTED, "");
119+
m_playlistLoader.ReloadPlayList();
128120
m_epg.ReloadEPG(); // Reloading EPG also updates media
129121

130122
m_reloadChannelsGroupsAndEPG = false;

src/iptvsimple/PlaylistLoader.cpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,33 @@ bool PlaylistLoader::Init()
3838
return true;
3939
}
4040

41+
namespace {
42+
43+
bool GetOverrideRealTime(std::string& line)
44+
{
45+
size_t realtimeIndex = line.find(REALTIME_OVERRIDE);
46+
if (realtimeIndex != std::string::npos)
47+
{
48+
size_t startValueIndex = realtimeIndex + REALTIME_OVERRIDE.length();
49+
size_t endQuoteIndex = line.find('"', startValueIndex);
50+
if (endQuoteIndex != std::string::npos)
51+
{
52+
size_t valueLength = endQuoteIndex - startValueIndex;
53+
std::string value = line.substr(startValueIndex, valueLength);
54+
StringUtils::ToLower(value);
55+
// The only value that matters is if the 'realtime' specifier is 'false'
56+
// that means we want to override the realtime value but not treat the stream
57+
// like media/VOD in the UI
58+
// It's a bit confusing, but hey, that's Kodi for you ;)
59+
return value == "false";
60+
}
61+
}
62+
63+
return false;
64+
}
65+
66+
}
67+
4168
bool PlaylistLoader::LoadPlayList()
4269
{
4370
auto started = std::chrono::high_resolution_clock::now();
@@ -64,6 +91,7 @@ bool PlaylistLoader::LoadPlayList()
6491
/* load channels */
6592
bool isFirstLine = true;
6693
bool isRealTime = true;
94+
bool overrideRealTime = false;
6795
bool isMediaEntry = false;
6896
int epgTimeShift = 0;
6997
int catchupCorrectionSecs = m_settings->GetCatchupCorrectionSecs();
@@ -149,6 +177,8 @@ bool PlaylistLoader::LoadPlayList()
149177
line.find(MEDIA_SIZE) != std::string::npos ||
150178
m_settings->MediaForcePlaylist();
151179

180+
overrideRealTime = GetOverrideRealTime(line);
181+
152182
const std::string groupNamesListString = ParseIntoChannel(line, tmpChannel, tmpMediaEntry, currentChannelGroupIdList, epgTimeShift, catchupCorrectionSecs, xeevCatchup);
153183

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

190-
if ((isRealTime || !m_settings->IsMediaEnabled() || !m_settings->ShowVodAsRecordings()) && !isMediaEntry)
220+
if ((isRealTime || overrideRealTime || !m_settings->IsMediaEnabled() || !m_settings->ShowVodAsRecordings()) && !isMediaEntry)
191221
{
192-
tmpChannel.AddProperty(PVR_STREAM_PROPERTY_ISREALTIMESTREAM, "true");
222+
// There are cases where we want the stream to be represetned as a channel with live streaming disabled
223+
// to allow features such as passthrough to work. We don't want this to be VOD as then it would be treated like media.
224+
if (!overrideRealTime)
225+
tmpChannel.AddProperty(PVR_STREAM_PROPERTY_ISREALTIMESTREAM, "true");
193226

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

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

212244
tmpChannel.Reset();
213245
tmpMediaEntry.Reset();
214246
isRealTime = true;
247+
overrideRealTime = false;
215248
isMediaEntry = false;
216249
channelHadGroups = false;
217250
}
@@ -535,7 +568,7 @@ void PlaylistLoader::ParseSinglePropertyIntoChannel(const std::string& line, Cha
535568
}
536569
}
537570

538-
bool PlaylistLoader::ReloadPlayList()
571+
void PlaylistLoader::ReloadPlayList()
539572
{
540573
m_m3uLocation = m_settings->GetM3ULocation();
541574

@@ -550,15 +583,11 @@ bool PlaylistLoader::ReloadPlayList()
550583
m_client->TriggerChannelGroupsUpdate();
551584
m_client->TriggerProvidersUpdate();
552585
m_client->TriggerRecordingUpdate();
553-
554-
return true;
555586
}
556587
else
557588
{
558589
m_channels.ChannelsLoadFailed();
559590
m_channelGroups.ChannelGroupsLoadFailed();
560-
561-
return false;
562591
}
563592
}
564593

src/iptvsimple/PlaylistLoader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ namespace iptvsimple
4848
static const std::string MEDIA = "media=";
4949
static const std::string MEDIA_DIR = "media-dir=";
5050
static const std::string MEDIA_SIZE = "media-size=";
51+
static const std::string REALTIME_OVERRIDE = "realtime=\"";
5152
static const std::string KODIPROP_MARKER = "#KODIPROP:";
5253
static const std::string EXTVLCOPT_MARKER = "#EXTVLCOPT:";
5354
static const std::string EXTVLCOPT_DASH_MARKER = "#EXTVLCOPT--";
@@ -71,7 +72,7 @@ namespace iptvsimple
7172
bool Init();
7273

7374
bool LoadPlayList();
74-
bool ReloadPlayList();
75+
void ReloadPlayList();
7576

7677
private:
7778
static std::string ReadMarkerValue(const std::string& line, const std::string& markerName);

0 commit comments

Comments
 (0)