diff --git a/pvr.eon/addon.xml.in b/pvr.eon/addon.xml.in
index b22b61b..dbc954d 100644
--- a/pvr.eon/addon.xml.in
+++ b/pvr.eon/addon.xml.in
@@ -6,7 +6,8 @@
provider-name="Nirvana">
@ADDON_DEPENDS@
-
+
+
diff --git a/pvr.eon/changelog.txt b/pvr.eon/changelog.txt
index 5df959a..b0976b8 100644
--- a/pvr.eon/changelog.txt
+++ b/pvr.eon/changelog.txt
@@ -9,7 +9,7 @@ v20.6.1
- Switch from adaptive to manual-osd for inputstream
- Fix not subscribed channels leading to crash
v20.7.0
- - Add Android TV platform (e.g. BigScreen/4K
+ - Add Android TV platform (e.g. BigScreen/4K)
v20.7.1
- Adapt user agent header for platforms when streaming
v20.7.2
diff --git a/pvr.eon/resources/language/resource.language.de_de/strings.po b/pvr.eon/resources/language/resource.language.de_de/strings.po
index cf27f2d..c30df98 100644
--- a/pvr.eon/resources/language/resource.language.de_de/strings.po
+++ b/pvr.eon/resources/language/resource.language.de_de/strings.po
@@ -231,3 +231,15 @@ msgstr "inputstream.adaptive"
msgctxt "#30053"
msgid "inputstream.ffmpegdirect"
msgstr "inputstream.ffmpegdirect"
+
+msgctxt "#30500"
+msgid "Inputstream error"
+msgstr "Inputstream Fehler"
+
+msgctxt "#30501"
+msgid "The %s addon is not installed."
+msgstr "Das %s Addon ist nicht installiert"
+
+msgctxt "#30502"
+msgid "The %s addon is not enabled."
+msgstr "Das %s Addon ist nicht aktiviert"
diff --git a/pvr.eon/resources/language/resource.language.en_gb/strings.po b/pvr.eon/resources/language/resource.language.en_gb/strings.po
index 5373fb6..fdf47a1 100644
--- a/pvr.eon/resources/language/resource.language.en_gb/strings.po
+++ b/pvr.eon/resources/language/resource.language.en_gb/strings.po
@@ -219,3 +219,15 @@ msgstr ""
msgctxt "#30053"
msgid "inputstream.ffmpegdirect"
msgstr ""
+
+msgctxt "#30500"
+msgid "Inputstream error"
+msgstr ""
+
+msgctxt "#30501"
+msgid "The %s addon is not installed."
+msgstr ""
+
+msgctxt "#30502"
+msgid "The %s addon is not enabled."
+msgstr ""
diff --git a/pvr.eon/resources/language/resource.language.en_us/strings.po b/pvr.eon/resources/language/resource.language.en_us/strings.po
index d3f1f1e..244036f 100644
--- a/pvr.eon/resources/language/resource.language.en_us/strings.po
+++ b/pvr.eon/resources/language/resource.language.en_us/strings.po
@@ -223,3 +223,15 @@ msgstr ""
msgctxt "#30053"
msgid "inputstream.ffmpegdirect"
msgstr ""
+
+msgctxt "#30500"
+msgid "Inputstream error"
+msgstr ""
+
+msgctxt "#30501"
+msgid "The %s addon is not installed."
+msgstr ""
+
+msgctxt "#30502"
+msgid "The %s addon is not enabled."
+msgstr ""
diff --git a/src/Globals.h b/src/Globals.h
index b465d08..0d052db 100644
--- a/src/Globals.h
+++ b/src/Globals.h
@@ -22,37 +22,10 @@ static const std::string CLIENT_SECRET_WEB = "1w4dmww87x1e9l89essqvc81pidrqsa0li
static const std::string CLIENT_ID_ATV = "5a3e24b8-70cd-4958-b716-af9ce053e594";
static const std::string CLIENT_SECRET_ATV = "aazy6orsi9elhhs17e47lfb4palgszw6igf4y26z";
-static const std::string SS_PORTAL = "https://mojtelemach.ba";
static const std::string SS_DOMAIN = "TBA";
static const std::string SS_USER = "webscuser";
static const std::string SS_SECRET = "k4md93!k334f3";
static const std::string SS_PASS = "xD8iMq1!m94z";
-//Web Client
-static const std::string API_PREFIX_WEB = "web";
-static const std::string API_SELECTOR_WEB = "be";
-static const std::string DEVICE_TYPE_WEB = "web_linux_chrome";
-static const std::string DEVICE_NAME_WEB = "";
-static const std::string DEVICE_MODEL_WEB = "Chrome 116";
-static const std::string DEVICE_PLATFORM_WEB = "web";
-static const std::string DEVICE_MAC_WEB = "";
-static const std::string CLIENT_SW_VERSION_WEB = "";
-static const std::string CLIENT_SW_BUILD_WEB = "";
-static const std::string SYSTEM_SW_WEB = "Linux";
-static const std::string SYSTEM_VERSION_WEB = "x86_64";
-static const std::string USER_AGENT_WEB = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36";
-//Android TV
-static const std::string API_PREFIX_ATV = "android-tv";
-static const std::string API_SELECTOR_ATV = "af31";
-static const std::string DEVICE_TYPE_ATV = "Android 11";
-static const std::string DEVICE_NAME_ATV = "Android TV 30";
-static const std::string DEVICE_MODEL_ATV = "SHIELD Android TV";
-static const std::string DEVICE_PLATFORM_ATV = "android_tv";
-static const std::string DEVICE_MAC_ATV = "";
-static const std::string CLIENT_SW_VERSION_ATV = "8.1.3";
-static const std::string CLIENT_SW_BUILD_ATV = "8.1.35906";
-static const std::string SYSTEM_SW_ATV = "Android";
-static const std::string SYSTEM_VERSION_ATV = "11";
-static const std::string USER_AGENT_ATV = "Mozilla/5.0 (Linux; Android 11; SHIELD Android TV Build/RQ1A.210105.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Mobile Safari/537.36; XDKAndroidWebView/3.0.1/XDKWebView NVIDIA NVIDIA/mdarcy/mdarcy:11/RQ1A.210105.003/7825230_3167.5736:user/release-keys NVIDIA AndroidTV 1.00A_ATV SHIELD Android TV Android/11 ExoPlayer ((1.00A_ATV::1.14.1::androidtv::)";
//LG TV
//static const std::string DEVICE_TYPE = "lgw-z81-8jg";
//static const std::string DEVICE_NAME = "LG WEB OS 2020";
diff --git a/src/PVREon.cpp b/src/PVREon.cpp
index 93cbfcf..5db850b 100644
--- a/src/PVREon.cpp
+++ b/src/PVREon.cpp
@@ -12,6 +12,7 @@
#include
#include
+#include
#include "Utils.h"
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
@@ -127,37 +128,30 @@ std::string aes_encrypt_cbc(const std::string &iv_str, const std::string &key, c
return output;
}
-bool CPVREon::Parametrize(const int id) {
- switch (id) {
- case 1:
- kodi::Log(ADDON_LOG_DEBUG,"Parametrizing for Android TV");
- m_parameters.api_prefix = API_PREFIX_ATV;
- m_parameters.api_selector = API_SELECTOR_ATV;
- m_parameters.device_type = DEVICE_TYPE_ATV;
- m_parameters.device_name = DEVICE_NAME_ATV;
- m_parameters.device_model = DEVICE_MODEL_ATV;
- m_parameters.device_platform = DEVICE_PLATFORM_ATV;
- m_parameters.device_mac = DEVICE_MAC_ATV;
- m_parameters.client_sw_version = CLIENT_SW_VERSION_ATV;
- m_parameters.client_sw_build = CLIENT_SW_BUILD_ATV;
- m_parameters.system_sw = SYSTEM_SW_ATV;
- m_parameters.system_version = SYSTEM_VERSION_ATV;
- m_parameters.user_agent = USER_AGENT_ATV;
- break;
- default:
- kodi::Log(ADDON_LOG_DEBUG,"Parametrizing for Web");
- m_parameters.api_prefix = API_PREFIX_WEB;
- m_parameters.api_selector = API_SELECTOR_WEB;
- m_parameters.device_type = DEVICE_TYPE_WEB;
- m_parameters.device_name = DEVICE_NAME_WEB;
- m_parameters.device_model = DEVICE_MODEL_WEB;
- m_parameters.device_platform = DEVICE_PLATFORM_WEB;
- m_parameters.device_mac = DEVICE_MAC_WEB;
- m_parameters.client_sw_version = CLIENT_SW_VERSION_WEB;
- m_parameters.client_sw_build = CLIENT_SW_BUILD_WEB;
- m_parameters.system_sw = SYSTEM_SW_WEB;
- m_parameters.system_version = SYSTEM_VERSION_WEB;
- m_parameters.user_agent = USER_AGENT_WEB;
+bool CPVREon::GetPostJson(const std::string& url, const std::string& body, rapidjson::Document& doc)
+{
+ int statusCode = 0;
+ std::string result;
+
+ if (body.empty()) {
+ result = m_httpClient->HttpGet(url, statusCode);
+ } else
+ {
+ // kodi::Log(ADDON_LOG_DEBUG, "Body: %s", body.c_str());
+ result = m_httpClient->HttpPost(url, body, statusCode);
+ }
+ //kodi::Log(ADDON_LOG_DEBUG, "Result: %s", result.c_str());
+ doc.Parse(result.c_str());
+ if ((doc.GetParseError()) || (statusCode != 200 && statusCode != 206))
+ {
+ kodi::Log(ADDON_LOG_ERROR, "Failed to get JSON %s status code: %i", url.c_str(), statusCode);
+ if (doc.HasMember("error") && doc.HasMember("errorMessage"))
+ {
+ std::string title = Utils::JsonStringOrEmpty(doc, "error");
+ std::string abstract = Utils::JsonStringOrEmpty(doc, "errorMessage");
+ kodi::gui::dialogs::OK::ShowAndGetInput(title, abstract);
+ }
+ return false;
}
return true;
}
@@ -220,15 +214,10 @@ std::string CPVREon::GetBaseApi(const std::string& cdn_identifier) {
std::string CPVREon::GetBrandIdentifier()
{
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(BROKER_URL + "v2/brands", statusCode);
+ std::string url = BROKER_URL + "v2/brands";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get brands");
return "";
}
@@ -254,15 +243,10 @@ std::string CPVREon::GetBrandIdentifier()
bool CPVREon::GetCDNInfo()
{
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(BROKER_URL + "v1/cdninfo", statusCode);
+ std::string url = BROKER_URL + "v1/cdninfo";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get cdninfo");
return false;
}
@@ -281,7 +265,7 @@ bool CPVREon::GetCDNInfo()
const rapidjson::Value& baseApi = cdnItem["domains"]["baseApi"];
- cdn.baseApi = Utils::JsonStringOrEmpty(baseApi, m_parameters.api_selector.c_str());
+ cdn.baseApi = Utils::JsonStringOrEmpty(baseApi, EonParameters[m_params].api_selector.c_str());
m_cdns.emplace_back(cdn);
}
@@ -290,17 +274,10 @@ bool CPVREon::GetCDNInfo()
bool CPVREon::GetDeviceData()
{
- std::string url = SS_PORTAL + "/gateway/SelfCareAPI/1.0/selfcareapi/" + SS_DOMAIN + "/subscriber/" + m_settings->GetSSIdentity() + "/devices/eon/2/product";
-
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(url, statusCode);
+ std::string url = m_support_web + "/gateway/SelfCareAPI/1.0/selfcareapi/" + SS_DOMAIN + "/subscriber/" + m_settings->GetSSIdentity() + "/devices/eon/2/product";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get self service product data");
return false;
}
@@ -328,38 +305,33 @@ bool CPVREon::GetDeviceData()
bool CPVREon::GetDeviceFromSerial()
{
- std::string jsonString;
- int statusCode = 0;
-
std::string postData;
- if (m_settings->GetPlatform() == 1) {
- postData = "{\"deviceName\":\"" + m_parameters.device_name +
- "\",\"deviceType\":\"" + m_parameters.device_type +
- "\",\"modelName\":\"" + m_parameters.device_model +
- "\",\"platform\":\"" + m_parameters.device_platform +
+ if (m_settings->GetPlatform() == PLATFORM_ANDROIDTV) {
+ postData = "{\"deviceName\":\"" + EonParameters[m_params].device_name +
+ "\",\"deviceType\":\"" + EonParameters[m_params].device_type +
+ "\",\"modelName\":\"" + EonParameters[m_params].device_model +
+ "\",\"platform\":\"" + EonParameters[m_params].device_platform +
"\",\"serial\":\"" + m_device_serial +
- "\",\"clientSwVersion\":\"" + m_parameters.client_sw_version +
- "\",\"clientSwBuild\":\"" + m_parameters.client_sw_build +
- "\",\"systemSwVersion\":{\"name\":\"" + m_parameters.system_sw +
- "\",\"version\":\"" + m_parameters.system_version +
+ "\",\"clientSwVersion\":\"" + EonParameters[m_params].client_sw_version +
+ "\",\"clientSwBuild\":\"" + EonParameters[m_params].client_sw_build +
+ "\",\"systemSwVersion\":{\"name\":\"" + EonParameters[m_params].system_sw +
+ "\",\"version\":\"" + EonParameters[m_params].system_version +
"\"},\"fcmToken\":\"\"}";
//TODO: implement parameter fcmToken...
} else {
- postData = "{\"deviceName\":\"\",\"deviceType\":\"" + m_parameters.device_type +
- "\",\"modelName\":\"" + m_parameters.device_model +
- "\",\"platform\":\"" + m_parameters.device_platform +
+ postData = "{\"deviceName\":\"\",\"deviceType\":\"" + EonParameters[m_params].device_type +
+ "\",\"modelName\":\"" + EonParameters[m_params].device_model +
+ "\",\"platform\":\"" + EonParameters[m_params].device_platform +
"\",\"serial\":\"" + m_device_serial +
- "\",\"clientSwVersion\":\"\",\"systemSwVersion\":{\"name\":\"" + m_parameters.system_sw +
- "\",\"version\":\"" + m_parameters.system_version + "\"}}";
+ "\",\"clientSwVersion\":\"\",\"systemSwVersion\":{\"name\":\"" + EonParameters[m_params].system_sw +
+ "\",\"version\":\"" + EonParameters[m_params].system_version + "\"}}";
}
- jsonString = m_httpClient->HttpPost(m_api + "v1/devices", postData, statusCode);
+ std::string url = m_api + "v1/devices";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, postData, doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get devices");
return false;
}
@@ -373,15 +345,10 @@ bool CPVREon::GetDeviceFromSerial()
bool CPVREon::GetServers()
{
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(m_api + "v1/servers", statusCode);
+ std::string url = m_api + "v1/servers";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get servers");
return false;
}
@@ -422,15 +389,10 @@ bool CPVREon::GetServers()
bool CPVREon::GetHouseholds()
{
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(m_api + "v1/households", statusCode);
+ std::string url = m_api + "v1/households";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get households");
return false;
}
@@ -443,15 +405,10 @@ bool CPVREon::GetHouseholds()
std::string CPVREon::GetTime()
{
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(m_api + "v1/time", statusCode);
+ std::string url = m_api + "v1/time";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get time");
return "";
}
@@ -461,20 +418,17 @@ std::string CPVREon::GetTime()
bool CPVREon::GetServiceProvider()
{
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(m_api + "v1/sp", statusCode);
+ std::string url = m_api + "v1/sp";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get service provider");
return false;
}
+
m_service_provider = Utils::JsonStringOrEmpty(doc, "identifier");
m_support_web = Utils::JsonStringOrEmpty(doc, "supportWebAddress");
+ m_httpClient->SetSupportApi(m_support_web);
kodi::Log(ADDON_LOG_DEBUG, "Got Service Provider: %s and Support Web: %s", m_service_provider.c_str(), m_support_web.c_str());
return true;
@@ -482,19 +436,13 @@ bool CPVREon::GetServiceProvider()
bool CPVREon::GetRenderingProfiles()
{
- std::string jsonString;
- int statusCode = 0;
-
- jsonString = m_httpClient->HttpGet(m_api + "v1/rndprofiles", statusCode);
+ std::string url = m_api + "v1/rndprofiles";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get rendering profiles");
return false;
}
- //kodi::Log(ADDON_LOG_DEBUG, "Got Rendering Profiles: %s", jsonString.c_str());
const rapidjson::Value& rndProfiles = doc;
@@ -520,23 +468,14 @@ bool CPVREon::GetRenderingProfiles()
bool CPVREon::GetCategories(const bool isRadio)
{
- std::string jsonString;
- int statusCode = 0;
-
- if (isRadio) {
- jsonString = m_httpClient->HttpGet(m_api + "v2/categories/RADIO", statusCode);
- } else {
- jsonString = m_httpClient->HttpGet(m_api + "v2/categories/TV", statusCode);
- }
+ std::string url = m_api + "v2/categories/" + (isRadio ? "RADIO" : "TV");
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to get categories");
return false;
}
- //kodi::Log(ADDON_LOG_DEBUG, "Got C: %s", m_service_provider.c_str());
+
const rapidjson::Value& categories = doc;
for (rapidjson::Value::ConstValueIterator itr1 = categories.Begin();
@@ -576,7 +515,9 @@ CPVREon::CPVREon() :
m_settings->Load();
m_httpClient = new HttpClient(m_settings);
- Parametrize(m_settings->GetPlatform());
+ m_params = m_settings->GetPlatform();
+ m_support_web = "API_NOT_SET_YET";
+ m_httpClient->SetSupportApi(m_support_web);
srand(time(nullptr));
@@ -584,24 +525,24 @@ CPVREon::CPVREon() :
std::string cdn_identifier = GetBrandIdentifier();
kodi::Log(ADDON_LOG_DEBUG, "CDN Identifier: %s", cdn_identifier.c_str());
std::string baseApi = GetBaseApi(cdn_identifier);
- m_api = "https://api-" + m_parameters.api_prefix + "." + baseApi + "/";
- m_images_api = "https://images-" + m_parameters.api_prefix + "." + baseApi + "/";
+ m_api = "https://api-" + EonParameters[m_params].api_prefix + "." + baseApi + "/";
+ m_images_api = "https://images-" + EonParameters[m_params].api_prefix + "." + baseApi + "/";
} else {
- m_api = "https://api-" + m_parameters.api_prefix + "." + GLOBAL_URL;
- m_images_api = "https://images-" + m_parameters.api_prefix + "." + GLOBAL_URL;
+ m_api = "https://api-" + EonParameters[m_params].api_prefix + "." + GLOBAL_URL;
+ m_images_api = "https://images-" + EonParameters[m_params].api_prefix + "." + GLOBAL_URL;
}
m_httpClient->SetApi(m_api);
kodi::Log(ADDON_LOG_DEBUG, "API set to: %s", m_api.c_str());
m_device_id = m_settings->GetEonDeviceID();
m_device_number = m_settings->GetEonDeviceNumber();
-
+/*
m_ss_identity = m_settings->GetSSIdentity();
if (m_ss_identity.empty()) {
m_httpClient->RefreshSSToken();
m_ss_identity = m_settings->GetSSIdentity();
}
-
+*/
if (m_device_id.empty() || m_device_number.empty()) {
/*
if (GetDeviceData()) {
@@ -670,20 +611,11 @@ ADDON_STATUS CPVREon::SetSetting(const std::string& settingName, const std::stri
bool CPVREon::LoadChannels(const bool isRadio)
{
kodi::Log(ADDON_LOG_DEBUG, "Load Eon Channels");
- std::string jsonString;
- int statusCode = 0;
-// std::string postData = "{}";
- if (isRadio) {
- jsonString = m_httpClient->HttpGet(m_api + "v3/channels?channelType=RADIO&channelSort=RECOMMENDED&sortDir=DESC", statusCode);
- } else {
- jsonString = m_httpClient->HttpGet(m_api + "v3/channels?channelType=TV", statusCode);
- }
+ std::string url = m_api + "v3/channels?channelType=" + (isRadio ? "RADIO&channelSort=RECOMMENDED&sortDir=DESC" : "TV");
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, "", doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to load channels");
return false;
}
@@ -815,15 +747,10 @@ bool CPVREon::HandleSession(bool start, int cid, int epg_id)
",\"viewing_time\":500,\"silent_event_change\":false}]";
kodi::Log(ADDON_LOG_DEBUG, "Session PostData: %s", postData.c_str());
- int statusCode = 0;
- std::string jsonString = m_httpClient->HttpPost("https://aes.ug.cdn.united.cloud/v1/events", postData, statusCode);
-
- kodi::Log(ADDON_LOG_DEBUG, "Event register returned: %s", jsonString.c_str());
+ std::string url = m_api + "v1/events";
rapidjson::Document doc;
- doc.Parse(jsonString.c_str());
- if (doc.GetParseError())
- {
+ if (!GetPostJson(url, postData, doc)) {
kodi::Log(ADDON_LOG_ERROR, "Failed to register event");
return false;
}
@@ -846,25 +773,39 @@ void CPVREon::SetStreamProperties(std::vector& p
if (inputstream == INPUTSTREAM_ADAPTIVE)
{
+ if (!Utils::CheckInputstreamInstalledAndEnabled("inputstream.adaptive"))
+ {
+ kodi::Log(ADDON_LOG_DEBUG, "inputstream.adaptive selected but not installed or enabled");
+ return;
+ }
+ kodi::Log(ADDON_LOG_DEBUG, "...using inputstream.adaptive");
properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "inputstream.adaptive");
properties.emplace_back("inputstream.adaptive.manifest_type", "hls");
// properties.emplace_back("inputstream.adaptive.original_audio_language", "bs");
// properties.emplace_back("inputstream.adaptive.stream_selection_type", "adaptive");
properties.emplace_back("inputstream.adaptive.stream_selection_type", "manual-osd");
- properties.emplace_back("inputstream.adaptive.manifest_headers", "User-Agent=" + m_parameters.user_agent);
- properties.emplace_back("inputstream.adaptive.manifest_update_parameter", "full");
+ properties.emplace_back("inputstream.adaptive.manifest_headers", "User-Agent=" + EonParameters[m_params].user_agent);
+ // properties.emplace_back("inputstream.adaptive.manifest_update_parameter", "full");
} else if (inputstream == INPUTSTREAM_FFMPEGDIRECT)
{
+ if (!Utils::CheckInputstreamInstalledAndEnabled("inputstream.ffmpegdirect"))
+ {
+ kodi::Log(ADDON_LOG_DEBUG, "inputstream.ffmpegdirect selected but not installed or enabled");
+ return;
+ }
+ kodi::Log(ADDON_LOG_DEBUG, "...using inputstream.ffmpegdirect");
properties.emplace_back(PVR_STREAM_PROPERTY_INPUTSTREAM, "inputstream.ffmpegdirect");
properties.emplace_back("inputstream.ffmpegdirect.manifest_type", "hls");
properties.emplace_back("inputstream.ffmpegdirect.is_realtime_stream", "true");
properties.emplace_back("inputstream.ffmpegdirect.stream_mode", isLive ? "timeshift" : "catchup");
+/*
if (!isLive) {
properties.emplace_back("inputstream.ffmpegdirect.catchup_buffer_start_time", std::to_string(starttime));
properties.emplace_back("inputstream.ffmpegdirect.catchup_buffer_end_time", std::to_string(endtime));
properties.emplace_back("inputstream.ffmpegdirect.programme_start_time", std::to_string(starttime));
- properties.emplace_back("inputstream.ffmpegdirect.programme_end_time", std::to_string(endtime));
+ properties.emplace_back("inputstream.ffmpegdirect.programme_end_time", std::to_string(endtime));
}
+*/
} else {
kodi::Log(ADDON_LOG_DEBUG, "Unknown inputstream detected");
}
@@ -932,28 +873,19 @@ PVR_ERROR CPVREon::GetEPGForChannel(int channelUid,
if (channel.iUniqueId != channelUid)
continue;
-
- std::string jsonEpg;
- int statusCode = 0;
-
kodi::Log(ADDON_LOG_DEBUG, "EPG Request for Channel %u Start %u End %u", channel.iUniqueId, start, end);
- std::string url = m_api + "v1/events/epg";
- std::string params = "?cid=" + std::to_string(channel.iUniqueId) +
- "&fromTime=" + std::to_string(start) + "000" +
- "&toTime=" + std::to_string(end) + "000";
-
- jsonEpg = m_httpClient->HttpGet(url + params, statusCode);
-
-// kodi::Log(ADDON_LOG_DEBUG, "EPG Events returned: %s", jsonEpg.c_str());
+ std::string url = m_api + "v1/events/epg" +
+ "?cid=" + std::to_string(channel.iUniqueId) +
+ "&fromTime=" + std::to_string(start) + "000" +
+ "&toTime=" + std::to_string(end) + "000";
rapidjson::Document epgDoc;
- epgDoc.Parse(jsonEpg.c_str());
- if (epgDoc.GetParseError())
- {
+ if (!GetPostJson(url, "", epgDoc)) {
kodi::Log(ADDON_LOG_ERROR, "[GetEPG] ERROR: error while parsing json");
return PVR_ERROR_SERVER_ERROR;
}
+
kodi::Log(ADDON_LOG_DEBUG, "[epg] iterate entries");
// std::string cid = "\"" + std::to_string(channel.referenceID) + "\"";
@@ -1110,7 +1042,7 @@ PVR_ERROR CPVREon::GetStreamProperties(
std::string plain_aes;
- if (m_settings->GetPlatform() == 1) {
+ if (m_settings->GetPlatform() == PLATFORM_ANDROIDTV) {
plain_aes = "channel=" + channel.publishingPoints[0].publishingPoint + ";" +
"stream=" + streaming_profile + ";" +
"sp=" + m_service_provider + ";" +
@@ -1168,14 +1100,14 @@ PVR_ERROR CPVREon::GetStreamProperties(
std::string enc_url = "https://" + currentServer.hostname +
"/stream?i=" + urlsafeencode(base64_encode(iv_str.c_str(), iv_str.length())) +
"&a=" + urlsafeencode(base64_encode(enc_str.c_str(), enc_str.length()));
- if (m_settings->GetPlatform() == 1) {
+ if (m_settings->GetPlatform() == PLATFORM_ANDROIDTV) {
enc_url = enc_url + "&lang=eng";
}
enc_url = enc_url + "&sp=" + m_service_provider +
"&u=" + m_settings->GetEonStreamUser() +
"&player=" + PLAYER +
"&session=" + m_session_id;
- if (m_settings->GetPlatform() != 1) {
+ if (m_settings->GetPlatform() != PLATFORM_ANDROIDTV) {
enc_url = enc_url + "&sig=" + channel.sig;
}
@@ -1298,7 +1230,7 @@ PVR_ERROR CPVREon::GetTimers(kodi::addon::PVRTimersResultSet& results)
{
return PVR_ERROR_NO_ERROR;
}
-
+/*
PVR_ERROR CPVREon::CallEPGMenuHook(const kodi::addon::PVRMenuhook& menuhook,
const kodi::addon::PVREPGTag& item)
{
@@ -1333,7 +1265,7 @@ PVR_ERROR CPVREon::CallSettingsMenuHook(const kodi::addon::PVRMenuhook& menuhook
PVR_ERROR CPVREon::CallMenuHook(const kodi::addon::PVRMenuhook& menuhook)
{
-/*
+
int iMsg;
switch (menuhook.GetHookId())
{
@@ -1353,10 +1285,9 @@ PVR_ERROR CPVREon::CallMenuHook(const kodi::addon::PVRMenuhook& menuhook)
return PVR_ERROR_INVALID_PARAMETERS;
}
kodi::QueueNotification(QUEUE_INFO, "", kodi::addon::GetLocalizedString(iMsg));
-*/
return PVR_ERROR_NO_ERROR;
}
-
+*/
bool CPVREon::GetChannel(const kodi::addon::PVRChannel& channel, EonChannel& myChannel)
{
kodi::Log(ADDON_LOG_DEBUG, "function call: [%s]", __FUNCTION__);
@@ -1399,7 +1330,7 @@ bool CPVREon::GetServer(bool isLive, EonServer& myServer)
servers = m_timeshift_servers;
}
int target_server = 2;
- if (m_settings->GetPlatform() == 1) {
+ if (m_settings->GetPlatform() == PLATFORM_ANDROIDTV) {
target_server = 3;
}
int count = 0;
diff --git a/src/PVREon.h b/src/PVREon.h
index b7ba59a..a9ab60f 100644
--- a/src/PVREon.h
+++ b/src/PVREon.h
@@ -17,6 +17,9 @@
static const int INPUTSTREAM_ADAPTIVE = 0;
static const int INPUTSTREAM_FFMPEGDIRECT = 1;
+static const int PLATFORM_WEB = 0;
+static const int PLATFORM_ANDROIDTV = 1;
+
struct EonChannelCategory
{
int id;
@@ -103,15 +106,15 @@ struct EonCDN
bool isDefault;
};
-struct EonParameters
+struct EonParameter
{
std::string api_prefix;
std::string api_selector;
std::string device_type;
- std::string device_mac;
std::string device_name;
std::string device_model;
std::string device_platform;
+ std::string device_mac;
std::string client_sw_version;
std::string client_sw_build;
std::string system_sw;
@@ -119,6 +122,38 @@ struct EonParameters
std::string user_agent;
};
+EonParameter EonParameters[2] = {{
+ //Web Client
+ "web",
+ "be",
+ "web_linux_chrome",
+ "",
+ "Chrome 116",
+ "web",
+ "",
+ "",
+ "",
+ "Linux",
+ "x86_64",
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"
+ },
+ {
+ //Android TV
+ "android-tv",
+ "af31",
+ "Android 11",
+ "Android TV 30",
+ "SHIELD Android TV",
+ "android_tv",
+ "",
+ "8.1.3",
+ "8.1.35906",
+ "Android",
+ "11",
+ "Mozilla/5.0 (Linux; Android 11; SHIELD Android TV Build/RQ1A.210105.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Mobile Safari/537.36; XDKAndroidWebView/3.0.1/XDKWebView NVIDIA NVIDIA/mdarcy/mdarcy:11/RQ1A.210105.003/7825230_3167.5736:user/release-keys NVIDIA AndroidTV 1.00A_ATV SHIELD Android TV Android/11 ExoPlayer ((1.00A_ATV::1.14.1::androidtv::)"
+ }
+ };
+
class ATTR_DLL_LOCAL CPVREon : public kodi::addon::CAddonBase,
public kodi::addon::CInstancePVRClient
{
@@ -133,17 +168,6 @@ class ATTR_DLL_LOCAL CPVREon : public kodi::addon::CAddonBase,
PVR_ERROR GetCapabilities(kodi::addon::PVRCapabilities& capabilities) override;
PVR_ERROR GetDriveSpace(uint64_t& total, uint64_t& used) override;
-
- PVR_ERROR CallEPGMenuHook(const kodi::addon::PVRMenuhook& menuhook,
- const kodi::addon::PVREPGTag& item) override;
- PVR_ERROR CallChannelMenuHook(const kodi::addon::PVRMenuhook& menuhook,
- const kodi::addon::PVRChannel& item) override;
- PVR_ERROR CallTimerMenuHook(const kodi::addon::PVRMenuhook& menuhook,
- const kodi::addon::PVRTimer& item) override;
- PVR_ERROR CallRecordingMenuHook(const kodi::addon::PVRMenuhook& menuhook,
- const kodi::addon::PVRRecording& item) override;
- PVR_ERROR CallSettingsMenuHook(const kodi::addon::PVRMenuhook& menuhook) override;
-
PVR_ERROR GetEPGForChannel(int channelUid,
time_t start,
time_t end,
@@ -193,8 +217,6 @@ class ATTR_DLL_LOCAL CPVREon : public kodi::addon::CAddonBase,
const EonChannel& channel,
std::vector& properties, const int& starttime, const int& endtime, const bool& isLive);
- bool Parametrize(const int id);
-
std::vector m_channels;
std::vector m_live_servers;
std::vector m_timeshift_servers;
@@ -224,6 +246,7 @@ class ATTR_DLL_LOCAL CPVREon : public kodi::addon::CAddonBase,
std::string m_api;
std::string m_images_api;
+ int m_params;
// std::string m_ss_refresh;
// int m_active_profile_id;
@@ -231,10 +254,10 @@ class ATTR_DLL_LOCAL CPVREon : public kodi::addon::CAddonBase,
HttpClient *m_httpClient;
CSettings* m_settings;
- EonParameters m_parameters;
std::string GetTime();
int getBitrate(const bool isRadio, const int id);
+ bool GetPostJson(const std::string& url, const std::string& body, rapidjson::Document& doc);
std::string getCoreStreamId(const int id);
std::string GetBaseApi(const std::string& cdn_identifier);
std::string GetBrandIdentifier();
diff --git a/src/Utils.cpp b/src/Utils.cpp
index abec0ca..d9ad631 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -238,3 +238,27 @@ std::string Utils::CreateUUID()
}
return uuid;
}
+
+bool Utils::CheckInputstreamInstalledAndEnabled(const std::string& inputstreamName)
+{
+ std::string version;
+ bool enabled;
+
+ if (kodi::IsAddonAvailable(inputstreamName, version, enabled))
+ {
+ if (!enabled)
+ {
+ std::string message = kodi::tools::StringUtils::Format(kodi::addon::GetLocalizedString(30502).c_str(), inputstreamName.c_str());
+ kodi::QueueNotification(QueueMsg::QUEUE_ERROR, kodi::addon::GetLocalizedString(30500), message);
+ return false;
+ }
+ }
+ else // Not installed
+ {
+ std::string message = kodi::tools::StringUtils::Format(kodi::addon::GetLocalizedString(30501).c_str(), inputstreamName.c_str());
+ kodi::QueueNotification(QueueMsg::QUEUE_ERROR, kodi::addon::GetLocalizedString(30500), message);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/Utils.h b/src/Utils.h
index 8e4bcab..c370199 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -26,4 +26,5 @@ class Utils
static double JsonDoubleOrZero(const rapidjson::Value& jsonValue, const char* fieldName);
static bool JsonBoolOrFalse(const rapidjson::Value& jsonValue, const char* fieldName);
static std::string CreateUUID();
+ static bool CheckInputstreamInstalledAndEnabled(const std::string& inputstreamName);
};
diff --git a/src/http/HttpClient.cpp b/src/http/HttpClient.cpp
index ee27a09..471cb83 100644
--- a/src/http/HttpClient.cpp
+++ b/src/http/HttpClient.cpp
@@ -15,6 +15,11 @@ void HttpClient::SetApi(const std::string& api)
m_api = api;
}
+void HttpClient::SetSupportApi(const std::string& supportApi)
+{
+ m_supportApi = supportApi;
+}
+
bool HttpClient::RefreshGenericToken()
{
Curl curl_auth;
@@ -57,7 +62,7 @@ bool HttpClient::RefreshSSToken()
{
Curl curl_auth;
- std::string url = SS_PORTAL + "/gateway/SCAuthAPI/1.0/scauth/auth/authentication"; //TODO: Fix URL
+ std::string url = m_supportApi + "/gateway/SCAuthAPI/1.0/scauth/auth/authentication"; //TODO: Fix URL
std::string refresh_token = m_settings->GetSSRefreshToken();
std::string access_token = m_settings->GetSSAccessToken();
std::string username = m_settings->GetEonUsername();
@@ -308,7 +313,7 @@ std::string HttpClient::HttpRequest(const std::string& action, const std::string
curl.AddHeader("User-Agent", EON_USER_AGENT);
- size_t found = url.find(SS_PORTAL);
+ size_t found = url.find(m_supportApi);
if (found != std::string::npos) {
access_token = m_settings->GetSSAccessToken();
if (!access_token.empty()) {
@@ -340,7 +345,7 @@ std::string HttpClient::HttpRequest(const std::string& action, const std::string
if (statusCode == 401) {
Curl curl_reauth;
- size_t found = url.find(SS_PORTAL);
+ size_t found = url.find(m_supportApi);
bool refresh_successful = true;
if (found != std::string::npos) {
if (RefreshSSToken()) {
diff --git a/src/http/HttpClient.h b/src/http/HttpClient.h
index 3509c29..7436247 100644
--- a/src/http/HttpClient.h
+++ b/src/http/HttpClient.h
@@ -21,6 +21,7 @@ class HttpClient
bool RefreshGenericToken();
void ClearSession();
void SetApi(const std::string& api);
+ void SetSupportApi(const std::string& supportApi);
std::string GetUUID();
void SetStatusCodeHandler(HttpStatusCodeHandler* statusCodeHandler) {
m_statusCodeHandler = statusCodeHandler;
@@ -31,6 +32,7 @@ class HttpClient
std::string GenerateUUID();
std::string m_uuid;
std::string m_api;
+ std::string m_supportApi;
std::string client_id;
std::string client_secret;
CSettings* m_settings;