pid) else: if pid in self.notyetreceived: print(self.spacing, "Received 1st of pid:", pid) self.notyetreceived.remove(pid) if self.scheduler.time >= nextchangetime: nextchangetime = self.scheduler.time + random.randrange( 10, 20) self.changeSubscription() self.notyetreceived = self.subscribed[:] if self.subscribed: self.pause() yield 1 print( "There's a delay of several seconds before you'll see any activity...") print("---1st subscriber:------|---2nd subscriber:------") Subscriber("MUX1", 0, 1, 2, 3, 4, 5).activate() Subscriber("MUX1", 25, 1, 2, 3, 4, 5).activate() from Kamaelia.Chassis.Pipeline import Pipeline from Kamaelia.Experimental.Services import RegisterService Pipeline( PacketSource(), RegisterService(DemuxerService(), {"MUX1": "request"}), ).run()
self.send( ("REMOVE", [audio_pid, video_pid], (self, "_av_packets")), "_toDemuxer") print time.asctime(), "Stopped", audio_pid, video_pid # ============================================================================== from Kamaelia.Device.DVB.Receiver import Receiver # DVB tuner and demultiplexer as a service, so other components can wire up # and request transport stream packets containing the pids they need RegisterService( Receiver(FREQUENCY, FE_PARAMS, 0), { "DEMUXER": "inbox" }, ).activate() # ------------------------------------------------------------------------------ # PSI table service - so other services, such as looking up channel names, mappings # of services to their audio & video pids etc. can get their tables from somewhere. # # Connects to the demuxer service, so it can request the relevant bits of data from Kamaelia.Device.DVB.Parse.ReassemblePSITables import ReassemblePSITablesService RegisterService( \ Graphline( PSI = ReassemblePSITablesService(), DEMUXER = ToService("DEMUXER"), linkages = {
def main(self): # get the demuxer service toDemuxer = self.addOutbox("toDemuxer") cat = CAT.getcat() service = cat.retrieveService(self.demuxerservice) self.link((self, toDemuxer), service) # create a PSI packet reconstructor, and wire it so it can ask # the demuxer for PIDs as required. psi = ReassemblePSITablesService() psi_service = RegisterService(psi, {"PSI": "request"}).activate() self.link((psi, "pid_request"), service) # stage 1, we need to get the service ID, so we'll query the SDT sdt_parser = Pipeline( Subscribe("PSI", [SDT_PID]), ParseServiceDescriptionTable_ActualTS()).activate() fromSDT = self.addInbox("fromSDT") fromSDT_linkage = self.link((sdt_parser, "outbox"), (self, fromSDT)) # wait until we get data back from the SDT # note that we wait until we find our service, there's no timeout service_id = None while service_id == None: while not self.dataReady(fromSDT): self.pause() yield 1 sdt_table = self.recv(fromSDT) transport_stream_id = sdt_table['transport_stream_id'] # see if we can find our services channel name for (sid, service) in sdt_table['services'].items(): for (dtype, descriptor) in service['descriptors']: if descriptor['type'] == "service": if descriptor['service_name'].lower( ) == self.channelname.lower(): service_id = sid break print "Found service id:", service_id print "Its in transport stream id:", transport_stream_id # stage 2, find out which PID contains the PMT for the service, # so we'll query the PAT pat_parser = Pipeline(Subscribe("PSI", [PAT_PID]), ParseProgramAssociationTable()).activate() fromPAT = self.addInbox("fromPAT") fromPAT_linkage = self.link((pat_parser, "outbox"), (self, fromPAT)) # wait until we get data back from the PAT PMT_PID = None while PMT_PID == None: while not self.dataReady(fromPAT): self.pause() yield 1 sdt_table = self.recv(fromPAT) # see if we can find our service's PMT ts_services = sdt_table['transport_streams'][transport_stream_id] if service_id in ts_services: PMT_PID = ts_services[service_id] break print "Found PMT PID for this service:", PMT_PID # stage 3, find out which PIDs contain AV data, so we'll query this # service's PMT pmt_parser = Pipeline(Subscribe("PSI", [PMT_PID]), ParseProgramMapTable()).activate() fromPMT = self.addInbox("fromPMT") fromPMT_linkage = self.link((pmt_parser, "outbox"), (self, fromPMT)) # wait until we get data back from the PMT audio_pid = None video_pid = None while audio_pid == None and video_pid == None: while not self.dataReady(fromPMT): self.pause() yield 1 pmt_table = self.recv(fromPMT) if service_id in pmt_table['services']: service = pmt_table['services'][service_id] for stream in service['streams']: if stream['type'] in [3, 4] and not audio_pid: audio_pid = stream['pid'] elif stream['type'] in [1, 2] and not video_pid: video_pid = stream['pid'] print "Found audio PID:", audio_pid print "Found video PID:", video_pid yield 1 # now set up to receive those pids and forward them on for all eternity fromDemuxer = self.addInbox("fromDemuxer") self.send(("ADD", [audio_pid, video_pid], (self, fromDemuxer)), toDemuxer) while 1: while self.dataReady(fromDemuxer): packet = self.recv(fromDemuxer) self.send(packet, "outbox") self.pause() yield 1
nextchangetime = self.scheduler.time + random.randrange( 10, 20) self.changeSubscription() self.notyetreceived = self.subscribed[:] if self.subscribed: self.pause() yield 1 from Kamaelia.Chassis.Pipeline import Pipeline from Kamaelia.Experimental.Services import RegisterService feparams = { "inversion": dvb3.frontend.INVERSION_AUTO, "constellation": dvb3.frontend.QAM_16, "code_rate_HP": dvb3.frontend.FEC_3_4, "code_rate_LP": dvb3.frontend.FEC_3_4, } print("Tunes to UK Crystal palace transmitter MUX 1") print("Subscribers subscribe to PIDs that should contain data") print("May take several seconds before you see any activity...") print("---1st subscriber:------|---2nd subscriber:------") Subscriber("MUX1", 0, 0, 0x11, 0x12, 600, 601).activate() Subscriber("MUX1", 25, 0, 0x11, 0x12, 600, 601).activate() demux = Receiver(505833330.0 / 1000000.0, feparams) RegisterService(demux, {"MUX1": "inbox"}).run()
self.pause() yield 1 if __name__ == "__main__": from Kamaelia.Util.Console import ConsoleEchoer from Kamaelia.Chassis.Graphline import Graphline from Kamaelia.File.Writing import SimpleFileWriter import dvb3.frontend feparams = { "inversion": dvb3.frontend.INVERSION_AUTO, "constellation": dvb3.frontend.QAM_16, "code_rate_HP": dvb3.frontend.FEC_3_4, "code_rate_LP": dvb3.frontend.FEC_3_4, } from Kamaelia.Device.DVB.Receiver import Receiver RegisterService(Receiver(505833330.0 / 1000000.0, feparams), { "MUX1": "inbox" }).activate() Pipeline( DVB_TuneToChannel(channel="BBC ONE", fromDemuxer="MUX1"), SimpleFileWriter("bbc_one.ts"), ).run()