including audio track informations, event description, event title......
for information about the file format look in EN300468 (www.etsi.org)
make info button useable when playbacking a movie
self.log(1, "'record service' failed")
return False
else:
- prep_res = self.record_service.prepare(self.Filename + ".ts")
+ event_id = self.eit
+ if event_id is None:
+ event_id = -1
+ prep_res = self.record_service.prepare(self.Filename + ".ts", self.begin, self.end, event_id )
if prep_res:
self.log(2, "'prepare' failed: error %d" % prep_res)
self.record_service = None
m_eit_changed();
}
+void eDVBServiceEITHandler::inject(ePtr<eServiceEvent> &event, int nownext)
+{
+ if (nownext)
+ m_event_next = event;
+ else
+ m_event_now = event;
+ m_eit_changed();
+}
+
eDVBServiceEITHandler::eDVBServiceEITHandler()
{
CONNECT(m_EIT.tableReady, eDVBServiceEITHandler::EITready);
ePtr<eServiceEvent> m_event_now, m_event_next;
public:
eDVBServiceEITHandler();
-
+
+ void inject(ePtr<eServiceEvent> &event, int nownext);
void start(iDVBDemux *demux, int sid);
void startOther(iDVBDemux *demux, int sid);
def __init__(self, Event, Ref, callback=None):
self.cbFunc = callback
self.currentService=Ref
+ self.isRecording = len(Ref.ref.getPath())
self.event = Event
self["epg_description"] = ScrollLabel()
self["datetime"] = Label()
self["channel"] = Label()
self["duration"] = Label()
self["key_red"] = Button("")
- self["key_green"] = Button(_("Add timer"))
+ if self.isRecording:
+ self["key_green"] = Button("")
+ else:
+ self["key_green"] = Button(_("Add timer"))
self["key_yellow"] = Button("")
self["key_blue"] = Button("")
self["actions"] = ActionMap(["OkCancelActions", "EventViewActions"],
self.cbFunc(self.setEvent, self.setService, +1)
def timerAdd(self):
- newEntry = RecordTimerEntry(self.currentService, *parseEvent(self.event))
- self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
+ if not self.isRecording:
+ newEntry = RecordTimerEntry(self.currentService, *parseEvent(self.event))
+ self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
def timerEditFinished(self, answer):
if (answer[0]):
def setService(self, service):
self.currentService=service
- name = self.currentService.getServiceName()
- if name is not None:
- self["channel"].setText(name)
+ if self.isRecording:
+ self["channel"].setText(_("Recording"))
else:
- self["channel"].setText(_("unknown service"))
+ name = self.currentService.getServiceName()
+ if name is not None:
+ self["channel"].setText(name)
+ else:
+ self["channel"].setText(_("unknown service"))
def setEvent(self, event):
self.event = event
InfoBarEPG, InfoBarEvent, InfoBarServiceName, InfoBarSeek, InfoBarInstantRecord, \
InfoBarAudioSelection, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, \
InfoBarSubserviceSelection, InfoBarTuner, InfoBarShowMovies, InfoBarTimeshift, \
- InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport
+ InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView
from Screens.HelpMenu import HelpableScreen, HelpMenu
class MoviePlayer(Screen, InfoBarShowHide, InfoBarPowerKey, \
InfoBarMenu, \
InfoBarServiceName, InfoBarSeek, InfoBarShowMovies, InfoBarAudioSelection, HelpableScreen, InfoBarNotifications,
- InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport):
+ InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView):
def __init__(self, session, service):
Screen.__init__(self, session)
for x in HelpableScreen, InfoBarShowHide, InfoBarPowerKey, InfoBarMenu, \
InfoBarServiceName, InfoBarSeek, InfoBarShowMovies, \
- InfoBarAudioSelection, InfoBarNotifications, \
+ InfoBarAudioSelection, InfoBarNotifications, InfoBarSimpleEventView, \
InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport:
x.__init__(self)
from Screens.MessageBox import MessageBox
from Screens.Dish import Dish
from Screens.Standby import Standby
-from Screens.EventView import EventViewEPGSelect
+from Screens.EventView import EventViewEPGSelect, EventViewSimple
from Screens.MinuteInput import MinuteInput
from Components.Harddisk import harddiskmanager
assert menu.tagName == "menu", "root element in menu must be 'menu'!"
self.session.open(MainMenu, menu, menu.childNodes)
+class InfoBarSimpleEventView:
+ """ Opens the Eventview for now/next """
+ def __init__(self):
+ self["EPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
+ {
+ "showEventInfo": (self.openEventView, _("show event details")),
+ })
+
+ def openEventView(self):
+ self.epglist = [ ]
+ service = self.session.nav.getCurrentService()
+ ref = self.session.nav.getCurrentlyPlayingServiceReference()
+ info = service.info()
+ ptr=info.getEvent(0)
+ if ptr:
+ self.epglist.append(ptr)
+ ptr=info.getEvent(1)
+ if ptr:
+ self.epglist.append(ptr)
+ if len(self.epglist) > 0:
+ self.session.open(EventViewSimple, self.epglist[0], ServiceReference(ref), self.eventViewCallback)
+
+ def eventViewCallback(self, setEvent, setService, val): #used for now/next displaying
+ if len(self.epglist) > 1:
+ tmp = self.epglist[0]
+ self.epglist[0]=self.epglist[1]
+ self.epglist[1]=tmp
+ setEvent(self.epglist[0])
+
class InfoBarEPG:
""" EPG - Opens an EPG list when the showEPGList action fires """
def __init__(self):
event = None
try:
service = self.session.nav.getCurrentService()
- info = service.info()
- ev = info.getEvent(0)
- event = ev
+ epg = eEPGCache.getInstance()
+ event = epg.lookupEventTime(serviceref, -1, 0)
+ if event is None:
+ info = service.info()
+ ev = info.getEvent(0)
+ event = ev
except:
pass
-
+
if event is not None:
data = parseEvent(event)
begin = time.time()
end = begin + 3600 * 10
-
data = (begin, end, data[2], data[3], data[4])
else:
data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
~iRecordableService();
#endif
public:
- virtual RESULT prepare(const char *filename)=0;
+ virtual RESULT prepare(const char *filename, time_t begTime=-1, time_t endTime=-1, int eit_event_id=-1)=0;
virtual RESULT start()=0;
virtual RESULT stop()=0;
};
#include <lib/dvb/decoder.h>
#include <lib/service/servicedvbrecord.h>
+#include <lib/service/event.h>
#include <lib/dvb/metaparser.h>
#include <lib/dvb/tstools.h>
#include <lib/python/python.h>
#include <byteswap.h>
#include <netinet/in.h>
+#include <dvbsi++/event_information_section.h>
+
#ifndef BYTE_ORDER
#error no byte order defined!
#endif
res.push_back(m_ref.path + ".meta");
res.push_back(m_ref.path + ".ap");
res.push_back(m_ref.path + ".cuts");
+ res.push_back(m_ref.path + ".eit");
return 0;
}
to start recording from the data demux. */
m_cue = new eCueSheet();
m_first_program_info = 1;
- r = m_service_handler.tune((eServiceReferenceDVB&)m_reference, m_is_pvr, m_cue);
+ eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
+ r = m_service_handler.tune(service, m_is_pvr, m_cue);
+ if (m_is_pvr)
+ {
+ std::string filename = service.path;
+ filename.erase(filename.length()-2, 2);
+ filename+="eit";
+ int fd = ::open( filename.c_str(), O_RDONLY );
+ if ( fd > -1 )
+ {
+ __u8 buf[4096];
+ int rd = ::read(fd, buf, 4096);
+ ::close(fd);
+ if ( rd > 12 /*EIT_LOOP_SIZE*/ )
+ {
+ Event ev(buf);
+ ePtr<eServiceEvent> event = new eServiceEvent;
+ ePtr<eServiceEvent> empty;
+ event->parseFrom(&ev, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get());
+ m_event_handler.inject(event, 0);
+ m_event_handler.inject(empty, 1);
+ eDebug("injected");
+ }
+ }
+ }
m_event(this, evStart);
m_event((iPlayableService*)this, evSeekableStatusChanged);
return 0;
#include <lib/service/servicedvbrecord.h>
#include <lib/base/eerror.h>
+#include <lib/dvb/epgcache.h>
#include <fcntl.h>
}
}
-RESULT eDVBServiceRecord::prepare(const char *filename)
+RESULT eDVBServiceRecord::prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id)
{
m_filename = filename;
if (m_state == stateIdle)
- return doPrepare();
+ {
+ int ret = doPrepare();
+ if (!ret)
+ {
+ eEPGCache::getInstance()->Lock();
+ const eit_event_struct *event = 0;
+ if ( eit_event_id != -1 )
+ {
+ eDebug("query epg event id %d", eit_event_id);
+ eEPGCache::getInstance()->lookupEventId(m_ref, eit_event_id, event);
+ }
+ if ( !event && (begTime != -1 && endTime != -1) )
+ {
+ time_t queryTime = begTime + ((endTime-begTime)/2);
+ tm beg, end, query;
+ localtime_r(&begTime, &beg);
+ localtime_r(&endTime, &end);
+ localtime_r(&queryTime, &query);
+ eDebug("query stime %d:%d:%d, etime %d:%d:%d, qtime %d:%d:%d",
+ beg.tm_hour, beg.tm_min, beg.tm_sec,
+ end.tm_hour, end.tm_min, end.tm_sec,
+ query.tm_hour, query.tm_min, query.tm_sec);
+ eEPGCache::getInstance()->lookupEventTime(m_ref, queryTime, event);
+ }
+ if ( event )
+ {
+ eDebug("found event.. store to disc");
+ std::string fname = filename;
+ fname.erase(fname.length()-2, 2);
+ fname+="eit";
+ int fd = open(fname.c_str(), O_CREAT|O_WRONLY, 0777);
+ if (fd>-1)
+ {
+ int evLen=HILO(event->descriptors_loop_length)+12/*EIT_LOOP_SIZE*/;
+ int wr = ::write( fd, (unsigned char*)event, evLen );
+ if ( wr != evLen )
+ eDebug("eit write error (%m)");
+ ::close(fd);
+ }
+ }
+ eEPGCache::getInstance()->Unlock();
+ }
+ return ret;
+ }
else
return -1;
}
{
DECLARE_REF(eDVBServiceRecord);
public:
- RESULT prepare(const char *filename);
+ RESULT prepare(const char *filename, time_t begTime, time_t endTime, int eit_event_id);
RESULT start();
RESULT stop();
private: