@@ -20,9 +20,36 @@ using namespace iptvsimple;
2020using namespace iptvsimple ::data;
2121using namespace iptvsimple ::utilities;
2222
23+ namespace
24+ {
25+ bool SplitUrlProtocolOpts (const std::string& streamURL,
26+ std::string& url,
27+ std::string& encodedProtocolOptions)
28+ {
29+ size_t found = streamURL.find_first_of (' |' );
30+ if (found != std::string::npos)
31+ {
32+ // Headers found, split and url-encode them
33+ url = streamURL.substr (0 , found);
34+ const std::string& protocolOptions = streamURL.substr (found + 1 , streamURL.length ());
35+ encodedProtocolOptions = StreamUtils::GetUrlEncodedProtocolOptions (protocolOptions);
36+ return true ;
37+ }
38+ return false ;
39+ }
40+ } // unnamed namespace
41+
2342void 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)
2443{
25- if (ChannelSpecifiesInputstream (channel))
44+ // Check if the channel has explicitly set up the use of inputstream.adaptive,
45+ // if so, the best behaviour for media services is:
46+ // - Always add mimetype to prevent kodi core to make an HTTP HEADER requests
47+ // this because in some cases services refuse this request and can also deny downloads
48+ // - If requested by settings, always add the "user-agent" header to ISA properties
49+ const bool isISAdaptiveSet =
50+ channel.GetProperty (PVR_STREAM_PROPERTY_INPUTSTREAM) == INPUTSTREAM_ADAPTIVE;
51+
52+ if (!isISAdaptiveSet && ChannelSpecifiesInputstream (channel))
2653 {
2754 // Channel has an inputstream class set so we only set the stream URL
2855 properties.emplace_back (PVR_STREAM_PROPERTY_STREAMURL, streamURL);
@@ -40,7 +67,7 @@ void StreamUtils::SetAllStreamProperties(std::vector<kodi::addon::PVRStreamPrope
4067 streamType = StreamUtils::InspectStreamType (streamURL, channel);
4168
4269 // Using kodi's built in inputstreams
43- if (StreamUtils::UseKodiInputstreams (streamType, settings))
70+ if (!isISAdaptiveSet && StreamUtils::UseKodiInputstreams (streamType, settings))
4471 {
4572 std::string ffmpegStreamURL = StreamUtils::GetURLWithFFmpegReconnectOptions (streamURL, streamType, channel, settings);
4673
@@ -83,19 +110,17 @@ void StreamUtils::SetAllStreamProperties(std::vector<kodi::addon::PVRStreamPrope
83110 // If no media headers are explicitly set for inputstream.adaptive,
84111 // strip the headers from streamURL and put it to media headers property
85112
86- if (channel.GetProperty (" inputstream.adaptive.stream_headers" ).empty ())
113+ if (channel.GetProperty (" inputstream.adaptive.manifest_headers" ).empty () &&
114+ channel.GetProperty (" inputstream.adaptive.stream_headers" ).empty ())
87115 {
88116 // No stream headers declared by property, check if stream URL has any
89- size_t found = streamURL.find_first_of (' |' );
90- if (found != std::string::npos)
117+ std::string url;
118+ std::string encodedProtocolOptions;
119+ if (SplitUrlProtocolOpts (streamURL, url, encodedProtocolOptions))
91120 {
92- // Headers found, split and url-encode them
93- const std::string& url = streamURL.substr (0 , found);
94- const std::string& protocolOptions = streamURL.substr (found + 1 , streamURL.length ());
95- const std::string& encodedProtocolOptions = StreamUtils::GetUrlEncodedProtocolOptions (protocolOptions);
96-
97121 // Set stream URL without headers and encoded headers as property
98122 properties.emplace_back (PVR_STREAM_PROPERTY_STREAMURL, url);
123+ properties.emplace_back (" inputstream.adaptive.manifest_headers" , encodedProtocolOptions);
99124 properties.emplace_back (" inputstream.adaptive.stream_headers" , encodedProtocolOptions);
100125 streamUrlSet = true ;
101126 }
@@ -105,9 +130,11 @@ void StreamUtils::SetAllStreamProperties(std::vector<kodi::addon::PVRStreamPrope
105130 if (!streamUrlSet)
106131 properties.emplace_back (PVR_STREAM_PROPERTY_STREAMURL, streamURL);
107132
108- properties.emplace_back (PVR_STREAM_PROPERTY_INPUTSTREAM, INPUTSTREAM_ADAPTIVE);
109- properties.emplace_back (" inputstream.adaptive.manifest_type" , StreamUtils::GetManifestType (streamType));
110- if (streamType == StreamType::HLS || streamType == StreamType::DASH)
133+ if (!isISAdaptiveSet)
134+ properties.emplace_back (PVR_STREAM_PROPERTY_INPUTSTREAM, INPUTSTREAM_ADAPTIVE);
135+
136+ if (streamType == StreamType::HLS || streamType == StreamType::DASH ||
137+ streamType == StreamType::SMOOTH_STREAMING)
111138 properties.emplace_back (PVR_STREAM_PROPERTY_MIMETYPE, StreamUtils::GetMimeType (streamType));
112139 }
113140 }
@@ -287,6 +314,8 @@ const std::string StreamUtils::GetMimeType(const StreamType& streamType)
287314 return " application/x-mpegURL" ;
288315 case StreamType::DASH:
289316 return " application/xml+dash" ;
317+ case StreamType::SMOOTH_STREAMING:
318+ return " application/vnd.ms-sstr+xml" ;
290319 case StreamType::TS:
291320 return " video/mp2t" ;
292321 default :
0 commit comments