Ejemplo n.º 1
0
    def channel_metadata(self, channel_number, rewind=0):
        channel_number = int(channel_number)
        rewind = int(rewind)

        if channel_number not in self.sbe.sxm.lineup:
            return self.file_not_found()

        channel = self.sbe.sxm.lineup[channel_number]
        channel_id = str(channel['channelKey'])
        packet = next(self.sbe.sxm.packet_generator(channel_id, rewind))
        metadata = None

        for pes_packet in mpegutils.parse_transport_stream(packet):
            if pes_packet['pid'] == 1024:
                for es_packet in mpegutils.parse_packetized_elementary_stream(pes_packet['payload']):
                    new_meta = mpegutils.parse_sxm_metadata(es_packet['payload'])
                    if not metadata and new_meta:
                        metadata = new_meta

        response = json.dumps({
            'channel': channel,
            'nowplaying': {
                'artist': metadata[1],
                'title': metadata[0],
                'album': metadata[2],
            },
        }, sort_keys=True, indent=4).encode('utf-8')

        self.send_standard_headers(len(response), {
            'Content-type': 'application/json',
        })

        self.wfile.write(response)
Ejemplo n.º 2
0
def media_segment(channel_number, segment):
    segment_data = sxm.get_segment(sxm.lineup[channel_number]["channelKey"], segment)

    audio = bytearray()
    metadata = bytearray()
    pcr = None

    for packet in mpegutils.parse_transport_stream(segment_data):
        if pcr == None and "pcr_base" in packet:
            pcr = packet["pcr_base"]
        if packet["pid"] == 768:
            audio += packet["payload"]
        elif packet["pid"] == 1024:
            metadata += packet["payload"]

    audio_adts = bytearray()
    for packet in mpegutils.parse_packetized_elementary_stream(audio):
        audio_adts += packet["payload"]

    id3 = mpegutils.create_id3(pcr, "Title", "Artist")

    return Response(id3 + audio_adts, mimetype="application/octet-stream")
Ejemplo n.º 3
0
def media_segment(channel_number, segment):
    segment_data = sxm.get_segment(sxm.lineup[channel_number]['channelKey'], segment)

    audio = bytearray()
    metadata = bytearray()
    pcr = None

    for packet in mpegutils.parse_transport_stream(segment_data):
        if pcr == None and 'pcr_base' in packet:
            pcr = packet['pcr_base']
        if packet['pid'] == 768:
            audio += packet['payload']
        elif packet['pid'] == 1024:
            metadata += packet['payload']

    audio_adts = bytearray()
    for packet in mpegutils.parse_packetized_elementary_stream(audio):
        audio_adts += packet['payload']

    id3 = mpegutils.create_id3(pcr, 'Title', 'Artist')

    return Response(id3 + audio_adts, mimetype='application/octet-stream')
Ejemplo n.º 4
0
    def channel_metadata(self, channel_number, rewind=0):
        channel_number = int(channel_number)
        rewind = int(rewind)

        if channel_number not in self.sbe.sxm.lineup:
            return self.file_not_found()

        channel = self.sbe.sxm.lineup[channel_number]
        channel_id = str(channel['channelKey'])
        packet = next(self.sbe.sxm.packet_generator(channel_id, rewind))
        metadata = None

        for pes_packet in mpegutils.parse_transport_stream(packet):
            if pes_packet['pid'] == 1024:
                for es_packet in mpegutils.parse_packetized_elementary_stream(
                        pes_packet['payload']):
                    new_meta = mpegutils.parse_sxm_metadata(
                        es_packet['payload'])
                    if not metadata and new_meta:
                        metadata = new_meta

        response = json.dumps(
            {
                'channel': channel,
                'nowplaying': {
                    'artist': metadata[1],
                    'title': metadata[0],
                    'album': metadata[2],
                },
            },
            sort_keys=True,
            indent=4).encode('utf-8')

        self.send_standard_headers(len(response), {
            'Content-type': 'application/json',
        })

        self.wfile.write(response)
Ejemplo n.º 5
0
    channel_number = int(sys.argv[1])
    channel_key = sxm.lineup[channel_number]['channelKey']
    filename = sxm.lineup[channel_number]['name'] + ' ' + datetime.datetime.now().strftime("%y-%m-%d %H-%M") + '.aac'

    original_playlist = sxm.get_playlist(sxm.lineup[channel_number]['channelKey'])
    playlist = [x for x in original_playlist.splitlines() if x.endswith('.ts')]

    for segment in playlist:
        print(segment)
    
        segment_data = sxm.get_segment(channel_key, segment)

        audio = bytearray()
        metadata = bytearray()
        pcr = None

        for packet in mpegutils.parse_transport_stream(segment_data):
            if pcr == None and 'pcr_base' in packet:
                pcr = packet['pcr_base']
            if packet['pid'] == 768:
                audio += packet['payload']
            elif packet['pid'] == 1024:
                metadata += packet['payload']

        audio_adts = bytearray()
        for packet in mpegutils.parse_packetized_elementary_stream(audio):
            audio_adts += packet['payload']

        with open(filename, 'ab') as f:
            f.write(audio_adts)
Ejemplo n.º 6
0
    def channel_stream(self, channel_number, rewind=0):
        channel_number = int(channel_number)
        rewind = int(rewind)

        if channel_number not in self.sbe.sxm.lineup:
            return self.file_not_found()

        channel = self.sbe.sxm.lineup[channel_number]
        url = 'http://{}:{}/'.format(self.sbe.config('hostname'), self.sbe.config('port'))

        logging.info('Streaming: Channel #{} "{}" with rewind {}'.format(
            channel_number,
            channel['name'],
            rewind))

        self.protocol_version = 'ICY' # if we don't pretend to be shoutcast, doctors HATE us
        self.send_response_only(200)
        self.send_header('Content-type', 'audio/aacp')
        self.send_header('icy-br', '64')
        self.send_header('icy-name', channel['name'])
        self.send_header('icy-genre', channel['genre'])
        self.send_header('icy-url', url)
        self.send_header('icy-metaint', '32768')
        self.end_headers()

        channel_id = str(channel['channelKey'])
        track_title = ''
        start_time = None
        new_meta = False

        audio = bytearray()
        for ts_packet in self.sbe.sxm.packet_generator(channel_id, rewind):
            pes_streams = collections.defaultdict(bytearray)
            for pes_packet in mpegutils.parse_transport_stream(ts_packet):
                if 'payload' in pes_packet:
                    pes_streams[pes_packet['pid']].extend(pes_packet['payload'])

            for pid, pes_stream in pes_streams.items():
                for es_packet in mpegutils.parse_packetized_elementary_stream(pes_stream):
                    if pid == 768:
                        audio.extend(es_packet['payload'])
                    elif pid == 1024:
                        metadata = mpegutils.parse_sxm_metadata(es_packet['payload'])
                        if metadata:
                            new_title = '{} - {}'.format(metadata[1], metadata[0])
                            if new_title != track_title:
                                logging.info("Now playing: " + new_title)
                                track_title = new_title
                                new_meta = True

                    if len(audio) >= 32768:
                        if new_meta:
                            meta_title = ("StreamTitle='" + track_title.replace("'", '') + "';").encode('utf-8')
                            meta_length = math.ceil(len(meta_title) / 16)
                            meta_buffer = bytes((meta_length,)) + meta_title + (b'\x00' * ((meta_length * 16) - len(meta_title)))
                            new_meta = False
                            logging.debug('Metadata: ' + repr(meta_buffer))
                        else:
                            meta_buffer = b'\x00'
                        audio_interval = audio[:32768]
                        del audio[:32768]
                        try:
                            self.wfile.write(audio_interval)
                            self.wfile.write(meta_buffer)
                            if start_time != None and time.time() - start_time < 4:
                                time.sleep(4 - (time.time() - start_time))
                            start_time = time.time()
                        except (ConnectionResetError, ConnectionAbortedError) as e:
                            logging.info('Connection dropped: ' + str(e))
                            return
Ejemplo n.º 7
0
    channel_number = int(sys.argv[1])
    channel_key = sxm.lineup[channel_number]["channelKey"]
    filename = sxm.lineup[channel_number]["name"] + " " + datetime.datetime.now().strftime("%y-%m-%d %H-%M") + ".aac"

    original_playlist = sxm.get_playlist(sxm.lineup[channel_number]["channelKey"])
    playlist = [x for x in original_playlist.splitlines() if x.endswith(".ts")]

    for segment in playlist:
        print(segment)

        segment_data = sxm.get_segment(channel_key, segment)

        audio = bytearray()
        metadata = bytearray()
        pcr = None

        for packet in mpegutils.parse_transport_stream(segment_data):
            if pcr == None and "pcr_base" in packet:
                pcr = packet["pcr_base"]
            if packet["pid"] == 768:
                audio += packet["payload"]
            elif packet["pid"] == 1024:
                metadata += packet["payload"]

        audio_adts = bytearray()
        for packet in mpegutils.parse_packetized_elementary_stream(audio):
            audio_adts += packet["payload"]

        with open(filename, "ab") as f:
            f.write(audio_adts)
Ejemplo n.º 8
0
    def channel_stream(self, channel_number, rewind=0):
        channel_number = int(channel_number)
        rewind = int(rewind)

        if channel_number not in self.sbe.sxm.lineup:
            return self.file_not_found()

        channel = self.sbe.sxm.lineup[channel_number]
        url = 'http://{}:{}/'.format(self.sbe.config('hostname'),
                                     self.sbe.config('port'))

        logging.info('Streaming: Channel #{} "{}" with rewind {}'.format(
            channel_number, channel['name'], rewind))

        self.protocol_version = 'ICY'  # if we don't pretend to be shoutcast, doctors HATE us
        self.send_response_only(200)
        self.send_header('Content-type', 'audio/aacp')
        self.send_header('icy-br', '64')
        self.send_header('icy-name', channel['name'])
        self.send_header('icy-genre', channel['genre'])
        self.send_header('icy-url', url)
        self.send_header('icy-metaint', '32768')
        self.end_headers()

        channel_id = str(channel['channelKey'])
        track_title = ''
        start_time = None
        new_meta = False

        audio = bytearray()
        for ts_packet in self.sbe.sxm.packet_generator(channel_id, rewind):
            pes_streams = collections.defaultdict(bytearray)
            for pes_packet in mpegutils.parse_transport_stream(ts_packet):
                if 'payload' in pes_packet:
                    pes_streams[pes_packet['pid']].extend(
                        pes_packet['payload'])

            for pid, pes_stream in pes_streams.items():
                for es_packet in mpegutils.parse_packetized_elementary_stream(
                        pes_stream):
                    if pid == 768:
                        audio.extend(es_packet['payload'])
                    elif pid == 1024:
                        metadata = mpegutils.parse_sxm_metadata(
                            es_packet['payload'])
                        if metadata:
                            new_title = '{} - {}'.format(
                                metadata[1], metadata[0])
                            if new_title != track_title:
                                logging.info("Now playing: " + new_title)
                                track_title = new_title
                                new_meta = True

                    if len(audio) >= 32768:
                        if new_meta:
                            meta_title = ("StreamTitle='" +
                                          track_title.replace("'", '') +
                                          "';").encode('utf-8')
                            meta_length = math.ceil(len(meta_title) / 16)
                            meta_buffer = bytes(
                                (meta_length, )) + meta_title + (b'\x00' * (
                                    (meta_length * 16) - len(meta_title)))
                            new_meta = False
                            logging.debug('Metadata: ' + repr(meta_buffer))
                        else:
                            meta_buffer = b'\x00'
                        audio_interval = audio[:32768]
                        del audio[:32768]
                        try:
                            self.wfile.write(audio_interval)
                            self.wfile.write(meta_buffer)
                            if start_time != None and time.time(
                            ) - start_time < 4:
                                time.sleep(4 - (time.time() - start_time))
                            start_time = time.time()
                        except (ConnectionResetError,
                                ConnectionAbortedError) as e:
                            logging.info('Connection dropped: ' + str(e))
                            return