|
#!/usr/bin/env python |
|
# -*- coding: UTF-8 -*- |
|
from pydub import AudioSegment |
|
from pydub.playback import play |
|
from tinyscript import * |
|
|
|
|
|
__author__ = "Alexandre D'Hondt" |
|
__version__ = "3.0" |
|
__copyright__ = "A. D'Hondt" |
|
__license__ = "agpl-3.0" |
|
__doc__ = """ |
|
This simple tool, based on PyDub, allows to append audio files, filter the |
|
result as voice frequency and alter the playback speed. |
|
|
|
""" |
|
__examples__ = ["audio_dir -s 10 --voice"] |
|
|
|
|
|
class Song(object): |
|
def __init__(self, *song_files): |
|
self.__song = None |
|
self.append(*song_files) |
|
|
|
def append(self, *song_files): |
|
""" This appends song files to the current song. """ |
|
songs = [] if self.__song is None else [self.__song] |
|
for f in song_files: |
|
from_method = "from_{}".format(Path(f).suffix[1:]) |
|
filename = Path(f).filename |
|
m = getattr(AudioSegment, from_method, "from_file") |
|
try: |
|
logger.debug("Trying to append '{}'...".format(filename)) |
|
songs.append(m(str(f))) |
|
logger.info("Appended: {}".format(filename)) |
|
except: |
|
logger.debug("An error occured while trying to append {}" |
|
" (AudioSegment.{})".format(filename, from_method)) |
|
logger.warning("Skipped: {}".format(filename)) |
|
if len(songs) > 0: |
|
self.__song = sum(songs) |
|
|
|
def export(self, filename): |
|
""" This exports the current song to a target file. """ |
|
if self.__song is None: |
|
return |
|
fmt = Path(filename).suffix[1:] |
|
try: |
|
self.__song.export(filename, format=fmt) |
|
logger.info("Created: {}".format(filename)) |
|
except Exception as e: |
|
logger.error("Error while exporting the song") |
|
logger.exception(e) |
|
|
|
def filter(self, low=None, high=None): |
|
""" This filters low and/or high frequencies. """ |
|
if self.__song is None: |
|
return |
|
if low is not None: |
|
logger.debug("Filtering low frequency...") |
|
self.__song = self.__song.low_pass_filter(low) |
|
if high is not None: |
|
logger.debug("Filtering high frequency...") |
|
self.__song = self.__song.high_pass_filter(high) |
|
|
|
def play(self): |
|
""" This plays the song. """ |
|
play(self.__song) |
|
|
|
def speedup(self, factor): |
|
""" This speeds up the song. """ |
|
if self.__song is None or factor == 1.0: |
|
return |
|
logger.debug("Changing playback speed...") |
|
self.__song = self.__song.speedup(playback_speed=factor) |
|
|
|
|
|
if __name__ == '__main__': |
|
parser.add_argument("items", nargs='+', |
|
help="folder with audio files or files themselves") |
|
parser.add_argument("-o", dest="output", default="audio.wav", |
|
help="output file") |
|
parser.add_argument("-q", dest="quiet", action="store_true", |
|
help="do not play the created audio") |
|
parser.add_argument("-s", dest="speedup", type=float, default=1.0, |
|
help="playback speed factor") |
|
parser.add_argument("--voice", action="store_true", |
|
help="filter voice frequency band") |
|
initialize() |
|
# running the main stuff |
|
s = Song() |
|
for i in args.items: |
|
p = Path(i) |
|
if p.is_dir(): |
|
for f in p.walk(): |
|
s.append(f) |
|
else: |
|
s.append(p) |
|
if args.voice: |
|
s.filter(300, 3000) |
|
s.speedup(args.speedup) |
|
s.export(args.output) |
|
if not args.quiet: |
|
s.play() |