Skip to content

Commit

Permalink
Merge pull request #882 from CastagnaIT/isa_improvs
Browse files Browse the repository at this point in the history
Improvements for InputStreamAdaptive
  • Loading branch information
phunkyfish authored Aug 24, 2024
2 parents 19f7304 + 73d4c38 commit 4d4d55e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 14 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="22.1.0"
version="22.1.1"
name="IPTV Simple Client"
provider-name="nightik and Ross Nicholson">
<requires>@ADDON_DEPENDS@
Expand Down
6 changes: 6 additions & 0 deletions pvr.iptvsimple/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v22.1.1
- Always add mimetype for inputstream.adaptive
- Better handled user-agent header for inputstream.adaptive use cases
- Fix missing manifest user-agent header for inputstream.adaptive
- Add missing SmoothStreaming mimetype for inputstream.adaptive

v22.1.0
- PVR Add-on API v9.0.0

Expand Down
55 changes: 42 additions & 13 deletions src/iptvsimple/utilities/StreamUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,36 @@ using namespace iptvsimple;
using namespace iptvsimple::data;
using namespace iptvsimple::utilities;

namespace
{
bool SplitUrlProtocolOpts(const std::string& streamURL,
std::string& url,
std::string& encodedProtocolOptions)
{
size_t found = streamURL.find_first_of('|');
if (found != std::string::npos)
{
// Headers found, split and url-encode them
url = streamURL.substr(0, found);
const std::string& protocolOptions = streamURL.substr(found + 1, streamURL.length());
encodedProtocolOptions = StreamUtils::GetUrlEncodedProtocolOptions(protocolOptions);
return true;
}
return false;
}
} // unnamed namespace

void StreamUtils::SetAllStreamProperties(std::vector<kodi::addon::PVRStreamProperty>& properties, const iptvsimple::data::Channel& channel, const std::string& streamURL, bool isChannelURL, std::map<std::string, std::string>& catchupProperties, std::shared_ptr<InstanceSettings>& settings)
{
if (ChannelSpecifiesInputstream(channel))
// Check if the channel has explicitly set up the use of inputstream.adaptive,
// if so, the best behaviour for media services is:
// - Always add mimetype to prevent kodi core to make an HTTP HEADER requests
// this because in some cases services refuse this request and can also deny downloads
// - If requested by settings, always add the "user-agent" header to ISA properties
const bool isISAdaptiveSet =
channel.GetProperty(PVR_STREAM_PROPERTY_INPUTSTREAM) == INPUTSTREAM_ADAPTIVE;

if (!isISAdaptiveSet && ChannelSpecifiesInputstream(channel))
{
// Channel has an inputstream class set so we only set the stream URL
properties.emplace_back(PVR_STREAM_PROPERTY_STREAMURL, streamURL);
Expand All @@ -40,7 +67,7 @@ void StreamUtils::SetAllStreamProperties(std::vector<kodi::addon::PVRStreamPrope
streamType = StreamUtils::InspectStreamType(streamURL, channel);

// Using kodi's built in inputstreams
if (StreamUtils::UseKodiInputstreams(streamType, settings))
if (!isISAdaptiveSet && StreamUtils::UseKodiInputstreams(streamType, settings))
{
std::string ffmpegStreamURL = StreamUtils::GetURLWithFFmpegReconnectOptions(streamURL, streamType, channel, settings);

Expand Down Expand Up @@ -83,19 +110,17 @@ void StreamUtils::SetAllStreamProperties(std::vector<kodi::addon::PVRStreamPrope
// If no media headers are explicitly set for inputstream.adaptive,
// strip the headers from streamURL and put it to media headers property

if (channel.GetProperty("inputstream.adaptive.stream_headers").empty())
if (channel.GetProperty("inputstream.adaptive.manifest_headers").empty() &&
channel.GetProperty("inputstream.adaptive.stream_headers").empty())
{
// No stream headers declared by property, check if stream URL has any
size_t found = streamURL.find_first_of('|');
if (found != std::string::npos)
std::string url;
std::string encodedProtocolOptions;
if (SplitUrlProtocolOpts(streamURL, url, encodedProtocolOptions))
{
// Headers found, split and url-encode them
const std::string& url = streamURL.substr(0, found);
const std::string& protocolOptions = streamURL.substr(found + 1, streamURL.length());
const std::string& encodedProtocolOptions = StreamUtils::GetUrlEncodedProtocolOptions(protocolOptions);

// Set stream URL without headers and encoded headers as property
properties.emplace_back(PVR_STREAM_PROPERTY_STREAMURL, url);
properties.emplace_back("inputstream.adaptive.manifest_headers", encodedProtocolOptions);
properties.emplace_back("inputstream.adaptive.stream_headers", encodedProtocolOptions);
streamUrlSet = true;
}
Expand All @@ -105,9 +130,11 @@ void StreamUtils::SetAllStreamProperties(std::vector<kodi::addon::PVRStreamPrope
if (!streamUrlSet)
properties.emplace_back(PVR_STREAM_PROPERTY_STREAMURL, streamURL);

properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, INPUTSTREAM_ADAPTIVE);
properties.emplace_back("inputstream.adaptive.manifest_type", StreamUtils::GetManifestType(streamType));
if (streamType == StreamType::HLS || streamType == StreamType::DASH)
if (!isISAdaptiveSet)
properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, INPUTSTREAM_ADAPTIVE);

if (streamType == StreamType::HLS || streamType == StreamType::DASH ||
streamType == StreamType::SMOOTH_STREAMING)
properties.emplace_back(PVR_STREAM_PROPERTY_MIMETYPE, StreamUtils::GetMimeType(streamType));
}
}
Expand Down Expand Up @@ -287,6 +314,8 @@ const std::string StreamUtils::GetMimeType(const StreamType& streamType)
return "application/x-mpegURL";
case StreamType::DASH:
return "application/xml+dash";
case StreamType::SMOOTH_STREAMING:
return "application/vnd.ms-sstr+xml";
case StreamType::TS:
return "video/mp2t";
default:
Expand Down

0 comments on commit 4d4d55e

Please sign in to comment.