Skip to content

Commit

Permalink
Merge pull request #3970 from DimitarCC/iptv-services-track-selection
Browse files Browse the repository at this point in the history
  • Loading branch information
littlesat committed May 8, 2024
2 parents 5abdd71 + ebacf9b commit 059b742
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 6 deletions.
151 changes: 151 additions & 0 deletions lib/dvb/db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@
#include <dvbsi++/s2_satellite_delivery_system_descriptor.h>
#include <dirent.h>
#include <lib/nav/core.h>
#include <fstream>

void join_str(const std::vector<std::string>& v, char c, std::string& s) {

s.clear();

for (std::vector<std::string>::const_iterator p = v.begin();
p != v.end(); ++p) {
s += *p;
if (p != v.end() - 1)
s += c;
}
}


/*
* Copyright (C) 2017 Marcus Metzler <mocm@metzlerbros.de>
Expand Down Expand Up @@ -416,6 +430,61 @@ void eDVBService::setCacheEntry(cacheID id, int pid)
initCache();
if (id < cacheMax)
m_cache[id] = pid;

if (!m_reference_str.empty()) {
bool hasFoundItem = false;
std::vector<eIPTVDBItem> &iptv_services = eDVBDB::getInstance()->iptv_services;
for(std::vector<eIPTVDBItem>::iterator it = iptv_services.begin(); it != iptv_services.end(); ++it) {
if (m_reference_str.find(it->s_ref) != std::string::npos) {
hasFoundItem = true;
int pid_val = pid > 0 ? pid : -1;
switch (id)
{
case cacheID::cMPEGAPID:
it->ampeg_pid = pid_val;
break;
case cacheID::cAC3PID:
it->aac3_pid = pid_val;
break;
case cacheID::cAC4PID:
it->aac4_pid = pid_val;
break;
case cacheID::cAACHEAPID:
it->aaach_pid = pid_val;
break;
case cacheID::cAACAPID:
it->aaac_pid = pid_val;
break;
case cacheID::cDDPPID:
it->addp_pid = pid_val;
break;
case cacheID::cDRAAPID:
it->adra_pid = pid_val;
break;
case cacheID::cSUBTITLE:
it->subtitle_pid = pid_val;
break;
case cacheID::cVPID:
it->v_pid = pid_val;
break;
default:
break;
}
break;
}
}
if (!hasFoundItem) {
std::vector<std::string> ref_split = split(m_reference_str, ":");
std::vector<std::string> ref_split_r(ref_split.begin(), ref_split.begin() + 10);
std::string ref_s;
join_str(ref_split_r, ':', ref_s);
int pid_val = pid > 0 ? pid : -1;
eIPTVDBItem item(ref_s, id == cacheID::cMPEGAPID ? pid_val : -1, id == cacheID::cAC3PID ? pid_val : -1, id == cacheID::cAC4PID ? pid_val : -1,
id == cacheID::cDDPPID ? pid_val : -1, id == cacheID::cAACHEAPID ? pid_val : -1, id == cacheID::cAACAPID ? pid_val : -1,
id == cacheID::cDRAAPID ? pid_val : -1, id == cacheID::cSUBTITLE ? pid_val : -1, id == cacheID::cVPID ? pid_val : -1);
iptv_services.push_back(item);
}
}
}

DEFINE_REF(eDVBDB);
Expand Down Expand Up @@ -461,6 +530,41 @@ void eDVBDB::parseServiceData(ePtr<eDVBService> s, std::string str)
s->m_ca.push_back((uint16_t)val);
}
}

std::string sref = s->m_reference_str;
if (!sref.empty()) {
for(std::vector<eIPTVDBItem>::iterator it = iptv_services.begin(); it != iptv_services.end(); ++it) {
if (sref.find(it->s_ref) != std::string::npos) {
if (it->v_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cVPID, it->v_pid);
}
if (it->ampeg_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cMPEGAPID, it->ampeg_pid);
}
if (it->aac3_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cAC3PID, it->aac3_pid);
}
if (it->aac4_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cAC4PID, it->aac4_pid);
}
if (it->addp_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cDDPPID, it->addp_pid);
}
if (it->aaach_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cAACHEAPID, it->aaach_pid);
}
if (it->aaac_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cAACAPID, it->aaac_pid);
}
if (it->adra_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cDRAAPID, it->adra_pid);
}
if (it->subtitle_pid != -1) {
s->setCacheEntry(eDVBService::cacheID::cSUBTITLE, it->subtitle_pid);
}
}
}
}
}

static ePtr<eDVBFrontendParameters> parseFrontendData(char* line, int version)
Expand Down Expand Up @@ -1011,6 +1115,25 @@ void eDVBDB::saveServicelist()
saveServicelist(eEnv::resolve("${sysconfdir}/enigma2/lamedb").c_str());
}

void eDVBDB::saveIptvServicelist()
{
std::ofstream outputFile("/etc/enigma2/config_av");
for(std::vector<eIPTVDBItem>::iterator it = iptv_services.begin(); it != iptv_services.end(); ++it) {
std::string line = it->s_ref + "|"
+ std::to_string(it->v_pid) + "|"
+ std::to_string(it->ampeg_pid) + "|"
+ std::to_string(it->aac3_pid) + "|"
+ std::to_string(it->aac4_pid) + "|"
+ std::to_string(it->addp_pid) + "|"
+ std::to_string(it->aaach_pid) + "|"
+ std::to_string(it->aaac_pid) + "|"
+ std::to_string(it->adra_pid) + "|"
+ std::to_string(it->subtitle_pid);
outputFile << line << '\n';
}
outputFile.close();
}

void eDVBDB::loadBouquet(const char *path)
{
std::vector<std::string> userbouquetsfiles;
Expand Down Expand Up @@ -1312,6 +1435,34 @@ eDVBDB::eDVBDB()
: m_numbering_mode(false), m_load_unlinked_userbouquets(true)
{
instance = this;

iptv_services.clear();
std::ifstream iptv_services_store_file;
iptv_services_store_file.open("/etc/enigma2/config_av");
std::string line = "";
while(getline(iptv_services_store_file, line))
{
line = replace_all(line, "\n", "");
std::vector<std::string> ref_split = split(line, "|");
std::vector<std::string> ref_split_r(ref_split.begin() + 1, ref_split.end());
std::string ref_s;
join_str(ref_split_r, '|', ref_s);
std::string s_ref = ref_split[0];
int ampeg_pid = -1;
int aac3_pid = -1;
int aac4_pid = -1;
int addp_pid = -1;
int aaach_pid = -1;
int aaac_pid = -1;
int adra_pid = -1;
int subtitle_pid = -1;
int video_pid = -1;
sscanf(ref_s.c_str(), "%d|%d|%d|%d|%d|%d|%d|%d|%d", &video_pid, &ampeg_pid, &aac3_pid, &aac4_pid, &addp_pid, &aaach_pid, &aaac_pid, &adra_pid, &subtitle_pid);
eIPTVDBItem iptvDBItem(s_ref, ampeg_pid, aac3_pid, aac4_pid, addp_pid, aaach_pid, aaac_pid, adra_pid, subtitle_pid, video_pid);
iptv_services.push_back(iptvDBItem);
line = "";
}
iptv_services_store_file.close();
reloadServicelist();
}

Expand Down
32 changes: 31 additions & 1 deletion lib/dvb/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,34 @@
#include <set>
#include <vector>
class ServiceDescriptionSection;

class eIPTVDBItem
{
public:
std::string s_ref;
int ampeg_pid;
int aac3_pid;
int aac4_pid;
int addp_pid;
int aaach_pid;
int aaac_pid;
int adra_pid;
int subtitle_pid;
int v_pid;
eIPTVDBItem(const std::string sref, const int ampegpid, const int aac3pid, const int aac4pid, const int addppid, const int aaachpid,
const int aaacpid, const int adrapid, const int subtitlepid, const int vpid) {
s_ref = sref;
ampeg_pid = ampegpid;
aac3_pid = aac3pid;
aac4_pid = aac4pid;
addp_pid = addppid;
aaach_pid = aaachpid;
aaac_pid = aaacpid;
adra_pid = adrapid;
subtitle_pid = subtitlepid;
v_pid = vpid;
};
};
#endif

class eDVBDB: public iDVBChannelList
Expand All @@ -29,7 +57,7 @@ class eDVBDB: public iDVBChannelList
std::map<eServiceReferenceDVB, ePtr<eDVBService> > m_services;

std::map<std::string, eBouquet> m_bouquets;

bool m_numbering_mode, m_load_unlinked_userbouquets;
#ifdef SWIG
eDVBDB();
Expand All @@ -38,6 +66,7 @@ class eDVBDB: public iDVBChannelList
private:
void loadServiceListV5(FILE * f);
public:
std::vector<eIPTVDBItem> iptv_services;
// iDVBChannelList
RESULT removeFlags(unsigned int flagmask, int dvb_namespace=-1, int tsid=-1, int onid=-1, unsigned int orb_pos=0xFFFFFFFF);
RESULT removeServices(int dvb_namespace=-1, int tsid=-1, int onid=-1, unsigned int orb_pos=0xFFFFFFFF);
Expand Down Expand Up @@ -86,6 +115,7 @@ class eDVBDB: public iDVBChannelList
static eDVBDB *getInstance() { return instance; }
void reloadServicelist();
void saveServicelist();
void saveIptvServicelist();
void saveServicelist(const char *file);
void reloadBouquets();
void parseServiceData(ePtr<eDVBService> s, std::string str);
Expand Down
2 changes: 2 additions & 0 deletions lib/dvb/idvb.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,10 @@ class eDVBService: public iStaticServiceInformation
cDATAPID, cPMTPID, cDRAAPID, cAC4PID, cacheMax
};

std::string m_reference_str;
int getCacheEntry(cacheID);
void setCacheEntry(cacheID, int);
void setServiceRef(std::string sref) { m_reference_str = sref; }

bool cacheEmpty();

Expand Down
12 changes: 10 additions & 2 deletions lib/python/Screens/AudioSelection.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
FOCUS_CONFIG, FOCUS_STREAMS = range(2)
[PAGE_AUDIO, PAGE_SUBTITLES] = ["audio", "subtitles"]


selectionpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_GUISKIN, "icons/audioselectionmark.png"))


def isIPTV(service):
path = service and service.getPath()
return path and not path.startswith("/") and service.type in [0x1, 0x1001, 0x138A, 0x1389]
class AudioSelection(ConfigListScreen, Screen):
def __init__(self, session, infobar=None, page=PAGE_AUDIO):
Screen.__init__(self, session)
Expand Down Expand Up @@ -84,6 +85,9 @@ def __layoutFinished(self):
self.focus = FOCUS_STREAMS
self.settings.menupage.addNotifier(self.fillList)

def saveAVDict(self):
eDVBDB.getInstance().saveIptvServicelist()

def fillList(self, arg=None):
streams = []
conflist = []
Expand Down Expand Up @@ -286,6 +290,8 @@ def changeAudio(self, audio):
if isinstance(track, int):
if self.session.nav.getCurrentService().audioTracks().getNumberOfTracks() > track:
self.audioTracks.selectTrack(track)
if isIPTV(ref):
self.saveAVDict()

def keyLeft(self):
if self.focus == FOCUS_CONFIG:
Expand Down Expand Up @@ -397,6 +403,8 @@ def keyOk(self):
config.subtitles.show.value = True
self.infobar.enableSubtitle(cur[0][:5])
self.__updatedInfo()
if isIPTV(ref):
self.saveAVDict()
self.close(0)
elif self.focus == FOCUS_CONFIG:
self.keyRight()
Expand Down
13 changes: 10 additions & 3 deletions lib/service/servicedvb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -994,12 +994,17 @@ RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServ
eDVBMetaParser parser;
int ret=parser.parseFile(ref.path);
service = new eDVBService;
std::string sref = ref.toString();
if (sref.find("%3a//") != std::string::npos && ret) {
service->setServiceRef(ref.toString());
eDVBDB::getInstance()->parseServiceData(service, "");
}
if (!ret)
eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
}
else
{
// TODO: handle the listing itself
// TODO: handle the listing itself
// if (ref.... == -1) .. return "... bouquets ...";
// could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
// TODO: cache
Expand Down Expand Up @@ -3321,8 +3326,9 @@ RESULT eDVBServicePlay::enableSubtitles(iSubtitleUser *user, SubtitleTrack &trac

m_subtitle_widget = user;
m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
if (m_dvb_service)
if (m_dvb_service){
m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
}
}
else
goto error_out;
Expand All @@ -3348,8 +3354,9 @@ RESULT eDVBServicePlay::disableSubtitles()
m_teletext_parser->setPageAndMagazine(-1, -1, "und");
m_subtitle_pages.clear();
}
if (m_dvb_service)
if (m_dvb_service){
m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, 0);
}
return 0;
}

Expand Down

0 comments on commit 059b742

Please sign in to comment.