Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Eda от Июль 09, 2017, 18:31



Название: QAudioBuffer
Отправлено: Eda от Июль 09, 2017, 18:31
Подскажите, как связать QAudioBuffer с QMediaPlayer?
Код
Python
       # Audio Player
       self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback)
       self.mediaPlayer.setVolume(25)
       self.songFile = ''
       self.mediaPlayer.positionChanged.connect(self.positionChanged)
       self.mediaPlayer.durationChanged.connect(self.durationChanged)
 
       buffer = QAudioBuffer()
 
       self.mediaProbe = QAudioProbe()
       self.mediaProbe.setSource(self.mediaPlayer)
       self.mediaProbe.audioBufferProbed.connect(lambda: self.processBuffer(buffer))
 
   def processBuffer(self, buffer):
       print(buffer.startTime())
 
В итоге startTime выдает -1 согласно документации это означает, что QAudioBuffer не связан ни с чем.
Загуглила все, что только можно, ни примеров на С++ ни тем более на питоне не нашла.

Суть такая: mediaPlayer проигрывает mp3 песню. Надо вытащить с буффера пики (peaks), чтобы потом сделать простецкий визуалайзер по типу такого:
(http://orig00.deviantart.net/4d96/f/2015/315/5/d/fountain_of_colors__desktop_music_visualizer_by_alatsombath-d8kxplv.png)
Может быть есть какие-то готовые примеры создания визуалайзера используя QT? Была бы непрочь ознакомиться  :)


Название: Re: QAudioBuffer
Отправлено: Гурман от Июль 16, 2017, 13:25
На Питоне не делал, делал на С++, и не с помощью QAudioProbe, а честно через QAudioInput. Всё работает.

Но вот в документации на Qt для С++ написано буквально следующее:

Цитировать
QAudioBuffer::QAudioBuffer()

Create a new, empty, invalid buffer.

То есть,
Код:
buffer = QAudioBuffer()
недостаточно, буфер необходимо инициализировать, использовать один из двух других конструкторов, либо с буфером QByteArray, либо с заданием числа сэмплов. И соответственно задать требуемый формат аудио. Думаю, что для Питона правило то же самое.


Название: Re: QAudioBuffer
Отправлено: Eda от Июль 17, 2017, 08:25
На Питоне не делал, делал на С++, и не с помощью QAudioProbe, а честно через QAudioInput. Всё работает.

Но вот в документации на Qt для С++ написано буквально следующее:

Цитировать
QAudioBuffer::QAudioBuffer()

Create a new, empty, invalid buffer.

То есть,
Код:
buffer = QAudioBuffer()
недостаточно, буфер необходимо инициализировать, использовать один из двух других конструкторов, либо с буфером QByteArray, либо с заданием числа сэмплов. И соответственно задать требуемый формат аудио. Думаю, что для Питона правило то же самое.
QAudioInput мне то как раз и не нужен. Нужно мп3-шку отловить, а не речь микрофона.
Может есть какой-то пример рабочий, даже на с++ чтобы наглядно посмотреть как оно делается, а то я пока ничего не поняла)


Название: Re: QAudioBuffer
Отправлено: Гурман от Июль 17, 2017, 13:22
Если нужны только данные о звуке для визуализации музыки, воспроизводимой QMediaPlayer, то для этого есть QAudioProbe. Примеров и обсуждений навалом, в том числе, в оригинальной документации на Qt. Правда не всё везде работает - вот тут (http://wiki.qt.io/Qt_5.5.0_Multimedia_Backends) есть табличка с перечнем функций, которые работают в разных ОС. Как видно, в Windows QAudioProbe не работает, если используется подсистема DirectShow.

Если нужен весь поток того, что воспроизводит QMediaPlayer, то я бы копал в сторону получения воспроизводимых данных в буфере через QIODevice *QMediaPlayer::mediaStream() и потом QByteArray QIODevice::read(qint64 maxSize). По идее там просто должны валить все сэмплы того, что воспроизводит QMediaPlayer. QAudioInput для этого не нужен - цифровой поток ведь целиком внутренний, QMediaPlayer его воспроизводит, значит можно получить поток от него, а не через вход. QAudioInput - это вообще ВВОД звука, то есть он совершенно сбоку от QMediaPlayer.

Но в случае если надо получить вообще всё, что воспроизводится устройством, то здесь есть проблема... Дело в том, что в разных ОС по-разному организованы воспроизведение и запись звука. В Windows есть такое устройство whatyouhear, это выход аудио-микшера. В принципе можно записывать с него, если использовать это устройство для ввода в QAudioInput. Но вообще-то это ещё зависит от возможностей аудио-оборудования - драйвер берёт выходной сигнал аудио-карты, если он доступен на конкретном железе, если у аудио-карты есть такой программный порт. Если нет, то ничего не получится. В Linux совсем другая звуковая система ALSA, в которой устройства называются иначе, и там не всегда получается скоммутировать внутренние сигналы, чтобы получить выход микшера. У меня на одном компьютере получилось, на другом нет - очевидно тоже зависит от оборудования. В Android, который вроде бы тоже Linux, вообще нет возможности поймать полный выходной сигнал микшера - это сделано, чтобы не нарушались авторские права, чтобы было невозможно записать воспроизводимую платную музыку. Как в MAC OS X и iOS я не знаю, но скорее всего тоже нет такой возможности.

В Android специально для визуализаций есть внутренний класс Visualizer, который выдаёт испорченный звук, но пригодный для визуализации (к сожалению, даже моно). Аналога его в Qt нет, пришлось обращаться к Java функциям через Native интерфейс. Это весьма не тривиально, но работает.

То есть, мультиплатформенное приложение, которое ловит и визуализирует весь воспроизводимый устройством звук, только на одном Qt не получится. Для каждой платформы придётся делать по-разному, с условной трансляцией.