def check_relay(self, eit): events = eit.events if events is None or len(events) < 1: return # only EITp/f is fed to this func, # so just check if the (1st) event exists ev = events[0] if ev is None or ev.descriptors is None: return desc = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.ISDBDescriptorType.EVENT_GROUP) if desc is None: return eg = desc.parse_event_group() if not eg[0] or eg[1] is None or len(eg[1].events) < 1: return if eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO_INTERNAL or \ eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO: if eg[1].events[0] is None: self.dprint("broken EIT(ev-grp desc. type:2/4) received.") return self.next_svcid = eg[1].events[0].service_id self.next_eid = eg[1].events[0].event_id if eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO and \ eg[1].events[0].transport_stream_id > 0: self.next_tsid = eg[1].events[0].transport_stream_id else: self.next_tsid = None self.dprint("will be relayed to ev:{0.next_eid}" "(svc:{0.next_svcid}) ts:{0.next_tsid}". format(self)) return
def check_ev_moved(self, eit, sid): events = eit.events if events is None or len(events) < 1: return # only EITp/f is fed to this func, # so just check if the (1st) event exists ev = events[0] if ev is None or ev.descriptors is None: return desc = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.ISDBDescriptorType.EVENT_GROUP) if desc is None: return eg = desc.parse_event_group() if not eg[0] or eg[1] is None or len(eg[1].events) < 1: return if eg[1].group_type != GstMpegts.EventGroupType.MOVED_FROM_INTERNAL: return for src in eg[1].events: if src.service_id == self.svc_id and src.event_id == self.ev_id: self.dprint("the evnet:{0}[svc:{1}] moved." " switching...".format(src.event_id, src.service_id)) self.next_svcid = sid self.next_eid = ev.event_id self.next_tsid = None self.switch_ev(self) return return
def check_relay(self, eit): events = eit.events if events is None or len(events) < 1: return # only EITp/f is fed to this func, # so just check if the (1st) event exists ev = events[0] if ev is None or ev.descriptors is None: return desc = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.ISDBDescriptorType.EVENT_GROUP) if desc is None: return eg = desc.parse_event_group() if not eg[0] or eg[1] is None or eg[1].event_count < 1: return if eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO_INTERNAL or \ eg[1].group_type == GstMpegts.EventGroupType.RELAYED_TO: if eg[1].events[0] is None: self.dprint("broken EIT(ev-grp desc. type:2/4) received.") return self.next_svcid = eg[1].events[0].service_id self.next_eid = eg[1].events[0].event_id if eg[1].group_type == GstMpegts.EventGroupType.RELAED_TO and \ eg[1].events[0].transport_stream_id > 0: self.next_tsid = eg[1].events[0].transport_stream_id else: self.next_tsid = None return
def check_ev_moved(self, eit, sid): events = eit.events if events is None or len(events) < 1: return # only EITp/f is fed to this func, # so just check if the (1st) event exists ev = events[0] if ev is None or ev.descriptors is None: return desc = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.ISDBDescriptorType.EVENT_GROUP) if desc is None: return eg = desc.parse_event_group() if not eg[0] or eg[1] is None or eg[1].event_count < 1: return if eg[1].group_type != GstMpegts.EventGroupType.MOVED_FROM_INTERNAL: return for i in range(eg.event_count): src = eg[1].events[i] if src.service_id == self.svc_id and src.event_id == self.ev_id: self.dprint("the evnet:{0}[0x{1:04x}] moved." " switching...".format(src.event_id, src.service_id)) self.next_svcid = sid self.next_eid = ev.event_id self.next_tsid = None self.switch_ev(self) return return
def proc_msg(message): st = message.get_structure() if st is None or not st.has_name('eit'): return try: sec = GstMpegts.message_parse_mpegts_section(message) eit = sec.get_eit() events = eit.events if verbose and eit.actual_stream and eit.present_following: print("EIT p/f:{} ver:{} eid:{} sid:{}".format( sec.section_number, sec.version_number, eit.events[0].event_id, sec.subtable_extension)) except (AttributeError, KeyError): sys.stderr.write('******* no events included.\n') return for ev in events: d = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.DVBDescriptorType.SHORT_EVENT) try: (title, txt) = d.parse_dvb_short_event()[2:4] if eit.present_following and \ eit.actual_stream and \ sec.section_number == 0 and \ title is not None: print(title) print(txt) print() except (AttributeError, TypeError): pass d = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.DVBDescriptorType.EXTENDED_EVENT) try: for desc in d.parse_dvb_extended_event(): for item in desc.items: print(item.item_descripton + ':') print(item.item) print() except AttributeError: pass
def proc_msg(message): st = message.get_structure() if st is None or not st.has_name('eit'): return try: sec = GstMpegts.message_parse_mpegts_section(message) eit = sec.get_eit() events = eit.events except (AttributeError, KeyError): sys.stderr.write('******* no events included.\n') return for ev in events: d = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.DVBDescriptorType.SHORT_EVENT) try: (title, txt) = d.parse_dvb_short_event()[2:4] if eit.present_following and \ eit.actual_stream and \ sec.section_number == 0 and \ title is not None: print(title) print(txt) print() except (AttributeError, TypeError): pass d = GstMpegts.find_descriptor(ev.descriptors, GstMpegts.DVBDescriptorType.EXTENDED_EVENT) try: for desc in d.parse_dvb_extended_event(): for item in desc.items: print(item.item_descripton + ':') print(item.item) print() except AttributeError: pass
def proc_eit(self, message): sec = GstMpegts.message_parse_mpegts_section(message) if sec is None: return st = message.get_structure() if self.watch_pat and st.has_name("pat"): self.check_pat(sec) return if not st.has_name("eit"): return eit = sec.get_eit() if eit is None: return if not (eit.actual_stream and eit.present_following): return if sec.subtable_extension != self.svc_id: if self.ev_id is not None and not self.found_ev: self.check_ev_moved(eit, sec.subtable_extension) return try: event = eit.events[0] # NOTE: time in EIT message is adjusted to UTC, # in accordance with the DVB standard. tm = event.start_time.to_g_date_time() dur = event.duration if sec.section_number > 1: self.dprint("broken EIT. no/bad section-number."); return; self.dprint("EIT. ID:%s sec:%s ver:%s" % (event.event_id, sec.section_number, sec.version_number)) if self.ev_id is None and \ self.is_target(sec.section_number == 0, tm, dur): self.ev_id = event.event_id self.dprint("selected event:%s ..." % self.ev_id) if sec.section_number == 0: # "tsparse" filters out the same-versioned table self.eit_ver_present = sec.version_number self.eit_eid_present = event.event_id evname = None desc = GstMpegts.find_descriptor(event.descriptors, GstMpegts.DVBDescriptorType.SHORT_EVENT) sh = desc.parse_dvb_short_event() if sh[0]: evname = sh[2] if evname is None or evname == "": self.eit_name_present = "???" else: self.eit_name_present = evname else: dur_undef = 165 * 3600 + 165 * 60 + 165 # FF:FF:FF as BCD if dur == dur_undef and tm.get_year() == 1900: return # "mpegtsparse" filters out the same-versioned table #if eit["version-number"] == self.eit_ver_following: # return self.eit_ver_following = sec.version_number self.eit_eid_following = event.event_id evname = None desc = GstMpegts.find_descriptor(event.descriptors, GstMpegts.DVBDescriptorType.SHORT_EVENT) sh = desc.parse_dvb_short_event() if sh[0]: evname = sh[2] if evname is None or evname == "": self.eit_name_following = "???" else: self.eit_name_following = evname # if event is still not identified, then return & wait subsequent EITs if self.ev_id is None: return if sec.section_number == 0 and \ self.ev_id == self.eit_eid_present: self.found_ev = True if self.ev_start is None and tm.get_year() != 1900: self.ev_start = tm.to_unix() self.valve(False) self.tsid = eit.transport_stream_id self.check_relay(eit) return elif sec.section_number == 1 and \ self.ev_id == self.eit_eid_following: self.found_ev = True if self.ev_start is None and tm.get_year() != 1900: self.ev_start = tm.to_unix() # check if the next event is close enough # but exclude the case for the starting period of unplanned pause. # in this case, the start time is set to the past. # (assert the updated EIT is the "following" one) now = time.time() if self.ev_start and \ self.ev_start >= now and self.ev_start - 5 <= now: self.valve(False) else: self.valve(True) self.tsid = eit.transport_stream_id self.check_relay(eit) return else: # check if in transient state for unplanned pause/break-ins # EITp has been updated first before EITf # to a new event (!self.ev_id). # Wait for the EITf update and # check if it == ev_id, i.e. pause/break-in. if self.recording and sec.section_number == 0 and \ self.eit_ver_present != self.eit_ver_following: self.valve(True) return # check if in state for initial waiting if not self.found_ev: return # EITf has been updated before EITp and # self.ev_id != eid_following (new value) & # self.ev_id != eid_present (old value). # Wait for the next EITp updated (to be ev_id). if sec.section_number == 1 and \ self.eit_ver_present != self.eit_ver_following and \ self.ev_id != self.eit_eid_present: return # wait until next EIT (section) update if self.ev_id == self.eit_eid_present or \ self.ev_id == self.eit_eid_following: return # check if a relayed-event exists if self.found_ev and self.next_eid: self.switch_ev() return self.valve(True) self.dprint("Finished recording.") self.quit() return except TypeError: self.dprint("broken EIT?. ignoring..."); return;
def proc_eit(self, message): sec = GstMpegts.message_parse_mpegts_section(message) if sec is None: return st = message.get_structure() if self.watch_pat and st.has_name("pat"): self.check_pat(sec) return if not st.has_name("eit"): return eit = sec.get_eit() if eit is None: return if not (eit.actual_stream and eit.present_following): return if sec.subtable_extension != self.svc_id: if self.ev_id is not None and not self.found_ev: self.check_ev_moved(eit, sec.subtable_extension) return try: event = eit.events[0] # NOTE: time in EIT message is adjusted to UTC, # in accordance with the DVB standard. tm = event.start_time.to_g_date_time() dur = event.duration if sec.section_number > 1: self.dprint("broken EIT. no/bad section-number."); return; if self.ev_id is None and \ self.is_target(sec.section_number == 0, tm, dur): self.ev_id = event.event_id self.dprint("selected event:%s ..." % self.ev_id) if sec.section_number == 0: # "tsparse" filters out the same-versioned table self.eit_ver_present = sec.version_number self.eit_eid_present = event.event_id evname = None desc = GstMpegts.find_descriptor(event.descriptors, GstMpegts.DVBDescriptorType.SHORT_EVENT) sh = desc.parse_dvb_short_event() if sh[0]: evname = sh[2] if evname is None or evname == "": self.eit_name_present = "???" else: self.eit_name_present = evname else: dur_undef = 165 * 3600 + 165 * 60 + 165 # FF:FF:FF as BCD if dur == dur_undef and tm.get_year() == 1900: return # "mpegtsparse" filters out the same-versioned table #if eit["version-number"] == self.eit_ver_following: # return self.eit_ver_following = sec.version_number self.eit_eid_following = event.event_id evname = None desc = GstMpegts.find_descriptor(event.descriptors, GstMpegts.DVBDescriptorType.SHORT_EVENT) sh = desc.parse_dvb_short_event() if sh[0]: evname = sh[2] if evname is None or evname == "": self.eit_name_following = "???" else: self.eit_name_following = evname if self.eit_eid_present and self.eit_eid_following and \ self.ev_id is None: self.ev_id = self.eit_eid_present self.dprint("selected event:%s ..." % self.ev_id) # if event is still not identified, then return & wait subsequent EITs if self.ev_id is None: return if self.ev_id == self.eit_eid_present: self.found_ev = True if self.ev_start is None and tm.get_year() != 1900: self.ev_start = tm.to_unix() self.valve(False) self.tsid = eit.transport_stream_id self.check_relay(eit) return elif self.ev_id == self.eit_eid_following: self.found_ev = True if self.ev_start is None and tm.get_year() != 1900: self.ev_start = tm.to_unix() # check if the next event is close enough # but exclude the case for the starting period of unplanned pause. # in this case, the start time is set to the past. # (assert the updated EIT is the "following" one) now = time.time() if sec.section_number == 1 and self.ev_start and \ self.ev_start >= now and self.ev_start - 5 <= now: self.valve(False) else: self.valve(True) self.tsid = eit.transport_stream_id self.check_relay(eit) return else: # check if in transient state for unplanned pause/break-ins if self.recording and sec.section_number == 0 and \ self.eit_ver_present != self.eit_ver_following: self.valve(True) return # check if in state for initial waiting if not self.found_ev: return # check if a relayed-event exists if self.recording and self.next_eid: self.switch_ev() return self.valve(True) self.dprint("Finished recording.") self.quit() return except TypeError: self.dprint("broken EIT?. ignoring..."); return;