示例#1
0
class Broadcaster:
    """
    After retreiving media streams from a venue, the broadcaster
    down-samples, transcodes, and mixes the audio into ulaw-8kHz format
    recognized by other media players. It also lets you select one video
    stream to forward. 
    """

    def __init__(self, name, app, mixAudio):
        global bridge
        
        self.flag = 1
        self.app = app
        self.processManager = ProcessManager()
        self.log = app.GetLog()

        self.selectAudio = 1
        
        if mixAudio:
            self.selectAudio = 0
    
        # Initiate multicast address allocator.
        self.multicastAddressAllocator = MulticastAddressAllocator()
        self.multicastAddressAllocator.SetAllocationMethod(
            MulticastAddressAllocator.RANDOM)
        self.multicastAddressAllocator.SetBaseAddress(MulticastAddressAllocator.SDR_BASE_ADDRESS)
        self.multicastAddressAllocator.SetAddressMask(MulticastAddressAllocator.SDR_MASK_SIZE)

        # Set host and port options
        self.toVideoHost = self.multicastAddressAllocator.AllocateAddress()
        self.toVideoPort = 8000
        self.toAudioHost = self.multicastAddressAllocator.AllocateAddress()
        self.toAudioPort = 6000
        self.transcoderHost = self.toAudioHost
        self.transcoderPort = int(self.toAudioPort) + 2
        
        # Register signal handling for clean shutdown of service.
        signal.signal(signal.SIGINT, self.StopSignalLoop)
        signal.signal(signal.SIGTERM, self.StopSignalLoop)

        self.StartProcesses()
                         
    def StartSignalLoop(self):
        '''
        Start loop that can get interrupted from signals and
        shut down service properly.
        '''
        
        self.flag = 1
        while self.flag:
            try:
                time.sleep(0.5)
            except IOError:
                self.flag = 0
                self.log.debug("Broadcaster.StartSignalLoop: Signal loop interrupted, exiting.")

    def StopSignalLoop(self, signum, frame):
        '''
        Signal callback that shuts down the service cleanly. 
        '''
        print "Exiting..."
        self.flag = 0
        bridge.stop()
        self.tcoder.Stop()
        self.StopProcesses()
    
    def StopProcesses(self):
        '''
        Shutdown all processes.
        '''
        self.processManager.TerminateAllProcesses()
        
    def StartProcesses(self):
        '''
        Start rat for audio mixing and selector for video selection.
        '''
        global bridge
        
        fromVideoHost = 0
        fromVideoPort = 0
        fromAudioHost = 0
        fromAudioPort = 0
               
        # Create venue proxy
        venueUrl = self.app.options.venueUrl
        if venueUrl:
            vProxy = venueProxy = VenueIW(venueUrl)
            

            # Get stream information from venue
            producerStreams = filter(lambda s: s.capability.role == "producer", vProxy.GetStreams())
            
            for stream in producerStreams:
                if stream.capability.type == "video":
                    fromVideoHost = stream.location.host
                    fromVideoPort = stream.location.port 
                if stream.capability.type == "audio":
                    fromAudioHost = stream.location.host
                    fromAudioPort = stream.location.port  

        else:
            fromVideoHost = self.app.options.videoHost
            fromVideoPort = int(self.app.options.videoPort)
            fromAudioHost = self.app.options.audioHost
            fromAudioPort = int(self.app.options.audioPort)
            
        if debug:
            print "video multicast: ", fromVideoHost, fromVideoPort
            print "audio multicast: ", fromAudioHost, fromAudioPort

        if fromVideoHost == 0 or fromVideoPort == 0:
            if debug: print "Video stream is not received from venue, you will not receive video"

        if fromAudioHost == 0 or fromAudioPort == 0:
            if debug: print "Audio stream is not received from venue, you will not receive audio"

        # We may receive odd ports from the venue (bug), so make
        # sure rtp only uses even ports .
        if fromVideoPort % 2 == 1:
            fromVideoPort = fromVideoPort -1

        if fromAudioPort % 2 == 1:
            fromAudioPort = fromAudioPort -1
        
        # Create commands to execute

        # Start audio down-sampler (linear16 kHz -> linear8 kHz)

        if debug: print "****************** START DOWN-SAMPLER", fromAudioHost, "/", fromAudioPort, "  ",self.transcoderHost, "/", self.transcoderPort
        self.tcoder = L16_to_L8(fromAudioHost,fromAudioPort,
                                self.transcoderHost,self.transcoderPort, self.selectAudio)
        self.tcoder.Start()

        wxapp = wxPySimpleApp()

        if self.selectAudio:
            audioSelectorUI = SelectorGUI("Audio Selector", self.tcoder)
       
        if debug: print "****************** BEFORE RAT", self.toAudioPort
        
        # Start audio transcoder (rat linear -> ulaw)
        ratExec = os.path.join(os.getcwd(), 'rat')
        roptions = []
        roptions.append("-T")
        roptions.append("%s/%d/127/l16"%(self.transcoderHost, int(self.transcoderPort)))
        roptions.append("%s/%d/127/pcm"%(self.toAudioHost, int(self.toAudioPort)))
              
        if debug: print "********* START transcoder ", ratExec, roptions, '\n'
        self.processManager.StartProcess(ratExec, roptions)


        self.vselector = VideoSelector(fromVideoHost, int(fromVideoPort),
                                       self.toVideoHost, int(self.toVideoPort), 1)
        self.vselector.Start()

        videoSelectorUI = SelectorGUI("VideoSelector", self.vselector)
        
        # Start video selector
        if debug: print "****************** START VIDEO SELECTOR", fromVideoHost, "/", fromVideoPort, "  ",self.toVideoHost, "/", self.toVideoPort
        
        if debug: print "----------------------------------------"
        if debug: print "*** Video from %s/%d is forwarded to %s/%d"%(fromVideoHost, fromVideoPort,
                                                            self.toVideoHost, self.toVideoPort)
        if debug: print "*** Audio from %s/%d is forwarded to %s/%d"%(fromAudioHost, fromAudioPort,
                                                            self.toAudioHost, self.toAudioPort)
        if debug: print "----------------------------------------"

        # Start the bridge
        print "Server URL: http://%s:%d" % (socket.gethostbyname(socket.gethostname()),9999)
        bridge = Bridge(self.toAudioHost, int(self.toAudioPort),
                        self.toVideoHost, int(self.toVideoPort), 9999)
         
        bridge.start()

        wxapp.SetTopWindow(videoSelectorUI)
        if self.selectAudio:
            audioSelectorUI.Show()
        videoSelectorUI.Show()
        wxapp.MainLoop()
示例#2
0
 def testSetGetBaseAddress(self):
     m = MulticastAddressAllocator()
     # this argument is for testing, it's may not be a valid base address.
     m.SetBaseAddress("127.0.0.1")
     assert "127.0.0.1" == m.GetBaseAddress()