Использование многопроцессорной обработки для пакетного преобразования .wav в .flac (Python, Pydub) - PullRequest
0 голосов
/ 03 июня 2018

Итак, я написал очень простую программу на Python 3, которая берет все аудиофайлы .wav в рабочем каталоге и конвертирует их в .flac.Не беспокойтесь о допущениях, которые он делает (например, допустимость файлов .wav, имена файлов уже существуют и т. Д.).См. Ниже:

import os
from multiprocessing import Pool
from pydub import AudioSegment

def worker(filename):
  song = AudioSegment.from_wav(filename)
  song.export(filename.replace(".wav",".flac"), format = "flac")

if __name__ == '__main__':
  converted_count = 0
  convertlist = []
  for filename in os.listdir(os.getcwd()):
    if filename.endswith(".wav"):
      convertlist.append(filename)
      converted_count += 1
  p = Pool(processes=min(converted_count, os.cpu_count()))
  p.map(worker, convertlist)

Я рассчитал это и в моей системе заметил значительное ускорение по сравнению с отсутствием многопроцессорной обработки вообще.Однако это кажется слишком простым;Я не очень разбираюсь в многопроцессорности (или многопоточности), поэтому честно говоря, я не уверен, есть ли более быстрый и эффективный способ сделать это.

Если вам поручили написать этот простой конвертер в Python,как бы ты это сделал?Что бы вы сделали, чтобы сделать его более эффективным?

Ответы [ 2 ]

0 голосов
/ 14 августа 2018

Если у вас много небольших файлов (например, аудиосэмплов для распознавания речи), так что преобразование одного файла занимает доли секунды, то вы можете сократить накладные расходы на планирование модуля многопроцессорной обработки, объединяя несколько файлов для преобразования, так что каждый процесс конвертирует более одного файла одновременно.Например, измените цикл имени файла или сгруппируйте элементы в convertlist и добавьте итерацию в worker.

0 голосов
/ 03 июня 2018

Пакет pydub, который вы используете в worker(), уже довольно эффективен, поскольку он поддерживается низкоуровневой медиа-библиотекой, которая не написана на Python: FFmpeg.То есть из-под капота pydub вызывает команду ffmpeg, используя модуль subprocess (см. код pydub ) для выполнения преобразования, в результате чего получается команда, которая выглядит следующим образом:

ffmpeg -y -f wav -i input.wav -write_xing 0 -f flac output.flac 

К сожалению, реализация кодера FLAC в FFmpeg не кажется распараллеленной, и поэтому невозможно улучшить скорость кодирования каждого независимого файла, сохраняя при этом то же качество кодирования, с этим конкретным кодером.Предполагая, что вы хотите продолжать использовать pydub и его кодировщик FFmpeg FLAC, ваш подход к проблеме, заключающийся в обработке каждого файла в отдельном процессе, звучит разумно.

Однако, если вы действительно хотите повысить производительность любой ценой,альтернативным вариантом будет обмен качества звука на скорость конвертации.Для этого вы можете настроить некоторые параметры кодирования, например, уменьшить частоту дискретизации:

# export the song with a lower sampling frequency
low_quality_song = song.set_frame_rate(11025)
low_quality_song.export(flac_filename, format="flac")

При этом, учитывая, что вы ориентируетесь на формат без потерь, переключитесь на более эффективный (потенциально GPU-основанный на) кодер, скорее всего, даст гораздо лучшие результаты при сохранении того же качества звука

...