LINUX.ORG.RU

gstreamer1 транслирование rtp потока с кешированием

 ,


1

1

Други, добрый день! Нужна помощь знатаков. Есть сервер генерации аудио потока по тексту (Разработка ЦРТ). Я ему запрос с текстом «Привет Мир!» а он мне по rtp играет мой текст. Этот сервак играет одновременно не более 10 потоков. У меня задача - закешировать rtp потоки. Написал сервер на python и заюзал gstreameer. Pipeline такие

play_rtp (когда не нашли в кеше текста, играем с сервака и кешируем)
caps такие: 'application/x-rtp,media=(string)audio, clock-rate=(int)8000, encoding-name=(string)PCMU, payload=(int)0'

udpsrc -> capsfilter(caps) -> tee -> queue -> udpsink  - транслируем
                         +  -> queue -> rtppcmudepay -> mulawdec -> audioconvert -> audioresample -> lamemp3enc -> filesink  - кешируем
play_file (когда нашли текст в кеше, играем из него)

здесь допом установлен mtu

filesrc -> mad -> audioconvert -> audioresample -> mulawenc -> rtppcmupay(mtu=172) -> udpsink

Проблема в том, что играю я все это в железку. Так первый pipeline проигрывается хорошо и сохраняется в файл. Второй (уже из файла) - проигрывается с некоторыми заиканиями... Я снял дамп на приемной стороне для обоих pipeline. Для первого каждый кадр всегда 172 байта. Во твором творился бардак от 10 до 1500 байт, в итоге, добавил параметр mtu = 172, качество проигрывания значительно улучшилось, но заикания все же есть. Дамп второго пайплайна показал 90% пакетов размером в 172 но есть и меньше (больших нет)... Подскажите, куда копать... может формат кеширования другой (пробовал с wav - еще хуже)

Вот код pipline

class Pipeline:

    def __init__(self, *a, **kw):
        self.pipeline = None
        self.current_elem = None

    @property
    def elements(self):
        ''' has to be iterable '''
        raise NotImplementedError()

    def configure(self, pipeline):
        self.current_elem = None
        for element in self.elements:
            pipeline.add(element)
            if self.current_elem:
                self.current_elem.link(element)
            self.current_elem = element
        return pipeline

    def start(self):
        self.pipeline = self.configure(Gst.Pipeline())
        ...


class PlayRtp(Pipeline):
    log = logging.getLogger('Play')
    caps = 'application/x-rtp,media=(string)audio, clock-rate=(int)8000, ' \
           'encoding-name=(string)PCMU, payload=(int)0'

    def __init__(self, in_host, in_port, out_host, out_port, tmp_path=None, *a, **kw):
        super().__init__(*a, **kw)
        self.in_host = in_host
        self.in_port = in_port
        self.out_host = out_host
        self.out_port = out_port
        self.tmp_path = tmp_path

    @property
    def elements(self):
        udpsrc = Gst.ElementFactory.make('udpsrc', 'udpsrc')
        udpsrc.set_property('address', self.in_host)
        udpsrc.set_property('port', self.in_port)
        yield udpsrc

        capsfilter = Gst.ElementFactory.make('capsfilter', 'capsfilter')
        capsfilter.set_property('caps', Gst.caps_from_string(self.caps))
        yield capsfilter

        udpsink = Gst.ElementFactory.make('udpsink', 'udpsink')
        udpsink.set_property('host', self.out_host)
        udpsink.set_property('port', self.out_port)
        if self.tmp_path:
            # transmit
            tee = Gst.ElementFactory.make('tee', 'tee')
            yield tee
            yield Gst.ElementFactory.make('queue', 'udp_queue')
            yield udpsink

            # save
            self.current_elem = tee
            yield Gst.ElementFactory.make('queue', 'write_queue')
            yield Gst.ElementFactory.make('rtppcmudepay', 'rtppcmudepay')
            yield Gst.ElementFactory.make('mulawdec', 'mulawdec')
            yield Gst.ElementFactory.make('audioconvert', 'audioconvert')
            yield Gst.ElementFactory.make('audioresample', 'audioresample')
            yield Gst.ElementFactory.make('lamemp3enc', 'lamemp3enc')
            filesink = Gst.ElementFactory.make('filesink', 'filesink')
            filesink.set_property('location', self.tmp_path)
            yield filesink
        else:
            # transmit
            yield udpsink

class PlayFile(Pipeline):
    log = logging.getLogger('Play')

    def __init__(self, host, port, path, mtu, *a, **kw):
        super().__init__(*a, **kw)
        self.host = host
        self.port = port
        self.path = path
        self.mtu = mtu

    @property
    def elements(self):
        filesrc = Gst.ElementFactory.make('filesrc', 'filesrc')
        filesrc.set_property('location', self.path)
        yield filesrc
        yield Gst.ElementFactory.make('mad', 'mad')
        yield Gst.ElementFactory.make('audioconvert', 'audioconvert')
        yield Gst.ElementFactory.make('audioresample', 'audioresample')
        yield Gst.ElementFactory.make('mulawenc', 'mulawenc')

        rtppcmupay = Gst.ElementFactory.make('rtppcmupay', 'rtppcmupay')
        rtppcmupay.set_property('mtu', self.mtu)
        yield rtppcmupay

        udpsink = Gst.ElementFactory.make('udpsink', 'udpsink')
        udpsink.set_property('host', self.host)
        udpsink.set_property('port', self.port)
        yield udpsink

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.