diff --git a/inputstream.ffmpegdirect/addon.xml.in b/inputstream.ffmpegdirect/addon.xml.in index f94fe92e..f3d8cc31 100644 --- a/inputstream.ffmpegdirect/addon.xml.in +++ b/inputstream.ffmpegdirect/addon.xml.in @@ -1,7 +1,7 @@ @ADDON_DEPENDS@ @@ -10,7 +10,7 @@ name="ffmpegdirect" extension="" tags="true" - listitemprops="program_number|stream_mode|open_mode|manifest_type|default_url|is_realtime_stream|playback_as_live|programme_start_time|programme_end_time|catchup_url_format_string|catchup_url_near_live_format_string|catchup_buffer_start_time|catchup_buffer_end_time|catchup_buffer_offset|catchup_terminates|catchup_granularity|timezone_shift|default_programme_duration|programme_catchup_id" + listitemprops="program_number|stream_mode|open_mode|manifest_type|stream_headers|default_url|is_realtime_stream|playback_as_live|programme_start_time|programme_end_time|catchup_url_format_string|catchup_url_near_live_format_string|catchup_buffer_start_time|catchup_buffer_end_time|catchup_buffer_offset|catchup_terminates|catchup_granularity|timezone_shift|default_programme_duration|programme_catchup_id" library_@PLATFORM@="@LIBRARY_FILENAME@" /> diff --git a/inputstream.ffmpegdirect/changelog.txt b/inputstream.ffmpegdirect/changelog.txt index 9bb6ae81..99edbd67 100644 --- a/inputstream.ffmpegdirect/changelog.txt +++ b/inputstream.ffmpegdirect/changelog.txt @@ -1,3 +1,6 @@ +v21.3.0 +- Add stream_headers property for the addon: to be appended to the stream URL after '|' + v21.2.0 - Kodi inputstream API update to version 3.3.0 diff --git a/src/StreamManager.cpp b/src/StreamManager.cpp index 86ca5d9e..607b6ab2 100644 --- a/src/StreamManager.cpp +++ b/src/StreamManager.cpp @@ -98,6 +98,10 @@ bool InputStreamFFmpegDirect::Open(const kodi::addon::InputstreamProperty& props { m_properties.m_manifestType = prop.second; } + else if (STREAM_HEADERS == prop.first) + { + m_properties.m_streamHeaders = prop.second; + } else if (DEFAULT_URL == prop.first) { m_properties.m_defaultUrl = prop.second; diff --git a/src/StreamManager.h b/src/StreamManager.h index 6edfdda3..2a1555e7 100644 --- a/src/StreamManager.h +++ b/src/StreamManager.h @@ -21,6 +21,7 @@ static const std::string IS_REALTIME_STREAM = "inputstream.ffmpegdirect.is_realt static const std::string STREAM_MODE = "inputstream.ffmpegdirect.stream_mode"; static const std::string OPEN_MODE = "inputstream.ffmpegdirect.open_mode"; static const std::string MANIFEST_TYPE = "inputstream.ffmpegdirect.manifest_type"; +static const std::string STREAM_HEADERS = "inputstream.ffmpegdirect.stream_headers"; static const std::string DEFAULT_URL = "inputstream.ffmpegdirect.default_url"; static const std::string PLAYBACK_AS_LIVE = "inputstream.ffmpegdirect.playback_as_live"; static const std::string PROGRAMME_START_TIME = "inputstream.ffmpegdirect.programme_start_time"; diff --git a/src/stream/FFmpegStream.cpp b/src/stream/FFmpegStream.cpp index 0996b446..61f44e7f 100644 --- a/src/stream/FFmpegStream.cpp +++ b/src/stream/FFmpegStream.cpp @@ -133,6 +133,7 @@ FFmpegStream::FFmpegStream(IManageDemuxPacket* demuxPacketManager, const Propert m_openMode(props.m_openMode), m_streamMode(props.m_streamMode), m_manifestType(props.m_manifestType), + m_streamHeaders(props.m_streamHeaders), m_curlInput(curlInput), m_httpProxy(httpProxy), m_paused(false) @@ -873,7 +874,7 @@ bool FFmpegStream::OpenWithFFmpeg(const AVInputFormat* iformat, const AVIOInterr AVDictionary* options = GetFFMpegOptionsFromInput(); CURL url; - url.Parse(m_streamUrl); + url.Parse(m_streamUrl, m_streamHeaders); //add prop here url.SetProtocolOptions(""); std::string strFile = url.Get(); @@ -956,7 +957,7 @@ bool FFmpegStream::OpenWithCURL(const AVInputFormat* iformat) Log(LOGLEVEL_INFO, "%s - IO handled by Kodi's cURL", __FUNCTION__); CURL url; - url.Parse(m_streamUrl); + url.Parse(m_streamUrl, m_streamHeaders); url.SetProtocolOptions(""); std::string strFile = url.Get(); @@ -2205,7 +2206,7 @@ std::string FFmpegStream::GetStreamCodecName(int iStreamId) AVDictionary* FFmpegStream::GetFFMpegOptionsFromInput() { CURL url; - url.Parse(m_streamUrl); + url.Parse(m_streamUrl, m_streamHeaders); AVDictionary* options = nullptr; // For a local file we need the following protocol whitelist diff --git a/src/stream/FFmpegStream.h b/src/stream/FFmpegStream.h index 73557856..d59de6dc 100644 --- a/src/stream/FFmpegStream.h +++ b/src/stream/FFmpegStream.h @@ -193,6 +193,7 @@ class FFmpegStream std::string m_mimeType; std::string m_programProperty; std::string m_manifestType; + std::string m_streamHeaders; bool m_opened; HttpProxy m_httpProxy; diff --git a/src/stream/url/URL.cpp b/src/stream/url/URL.cpp index a01f4b1c..8cdacbb5 100644 --- a/src/stream/url/URL.cpp +++ b/src/stream/url/URL.cpp @@ -176,14 +176,20 @@ void CURL::Reset() m_strFileType.clear(); m_strOptions.clear(); m_strProtocolOptions.clear(); + m_strProtocolOptionsExtraURLEncoded.clear(); m_options.Clear(); m_protocolOptions.Clear(); m_iPort = 0; } -void CURL::Parse(const std::string& strURL1) +void CURL::Parse(const std::string& strURL1, const std::string& strStreamHeaders) { Reset(); + + // This the stream_headers property sent to the add-on + // We store it here so we can add it when Get() is called. + m_strProtocolOptionsExtraURLEncoded = strStreamHeaders; + // start by validating the path std::string strURL = ValidatePath(strURL1); @@ -581,6 +587,7 @@ std::string CURL::Get() const + m_strFileName.length() + m_strOptions.length() + m_strProtocolOptions.length() + + m_strProtocolOptionsExtraURLEncoded.length() + 10; std::string strURL; @@ -591,8 +598,15 @@ std::string CURL::Get() const if( !m_strOptions.empty() ) strURL += m_strOptions; - if (!m_strProtocolOptions.empty()) - strURL += "|"+m_strProtocolOptions; + if (!m_strProtocolOptions.empty() || !m_strProtocolOptionsExtraURLEncoded.empty()) + { + if (!m_strProtocolOptions.empty() && !m_strProtocolOptionsExtraURLEncoded.empty()) + strURL += "|"+m_strProtocolOptions+"&"+m_strProtocolOptionsExtraURLEncoded; + else if (!m_strProtocolOptions.empty()) + strURL += "|"+m_strProtocolOptions; + else + strURL += "|"+m_strProtocolOptionsExtraURLEncoded; + } return strURL; } diff --git a/src/stream/url/URL.h b/src/stream/url/URL.h index 658503c3..9f8992dc 100644 --- a/src/stream/url/URL.h +++ b/src/stream/url/URL.h @@ -19,9 +19,9 @@ class CURL { public: - explicit CURL(const std::string& strURL) + explicit CURL(const std::string& strURL, const std::string& strStreamHeaders = "") { - Parse(strURL); + Parse(strURL, strStreamHeaders); } CURL() = default; @@ -31,7 +31,7 @@ class CURL bool operator==(const std::string &url) const { return Get() == url; } void Reset(); - void Parse(const std::string& strURL); + void Parse(const std::string& strURL, const std::string& strStreamHeaders); void SetFileName(const std::string& strFileName); void SetHostName(const std::string& strHostName) { @@ -196,6 +196,7 @@ class CURL std::string m_strFileType; std::string m_strOptions; std::string m_strProtocolOptions; + std::string m_strProtocolOptionsExtraURLEncoded; CUrlOptions m_options; CUrlOptions m_protocolOptions; }; diff --git a/src/utils/Properties.h b/src/utils/Properties.h index e068052e..d6eeb28a 100644 --- a/src/utils/Properties.h +++ b/src/utils/Properties.h @@ -34,6 +34,7 @@ namespace ffmpegdirect StreamMode m_streamMode = StreamMode::NONE; OpenMode m_openMode = OpenMode::DEFAULT; std::string m_manifestType; + std::string m_streamHeaders; std::string m_defaultUrl; bool m_playbackAsLive = false; @@ -48,6 +49,6 @@ namespace ffmpegdirect int m_catchupGranularity = 1; int m_timezoneShiftSecs = 0; int m_defaultProgrammeDurationSecs = 4 * 60 * 60; //Four hours - std::string m_programmeCatchupId; + std::string m_programmeCatchupId; }; } //namespace ffmpegdirect \ No newline at end of file