Compare commits

...
3 Commits
Author SHA1 Message Date
gryf 7a671a5a6d Make opus default encoder 2026-09-25 09:52:06 +02:00
gryf 5a45d56784 Added opus encoder and decoder 2026-09-25 09:49:37 +02:00
gryf 38dc4234e0 Use fstring intsead of string interpolation.
Also, removed python2 mentioning in readme.
2026-09-25 09:19:38 +02:00
2 changed files with 54 additions and 23 deletions

No files matched your search

+14 -8
View File
@@ -15,9 +15,10 @@ conversion between different type of audio formats.
Requirements
============
- python in version 2.7 or 3
- python 3
- `mutagen`_ python library for tag read/write
- `vorbis tools`_ for ``ogg`` files encode/decode
- `opus tools`_ for ``opus`` files encode/decode
- `lame`_ for ``mp3`` files encode/decode
- `flac`_ for ``flac`` files decode
- `mac`_ for ``Monkey audio codecs``/``ape`` files decode
@@ -37,16 +38,19 @@ Conversion can be performed from the following formats:
- WavePack
- Ape
- Ogg Vorbis
- Ogg Opus
Currently supported encoders:
- Ogg Vorbis
- Ogg Opus
- MP3 (lame)
There is an option to set the quality for the encoders - for *Ogg* files there
would be used an ``-q`` option for ``oggenc`` command, and for the *mp3*
format, ``-V`` option would be used for ``lame`` command. Consult corresponding
man pages for details.
There is an option to set the quality for the encoders - for *Vorbis* files
there would be used an ``-q`` option for ``oggenc`` command, for the *mp3*
format ``-V`` option would be used for ``lame`` command and ``--bitrate`` for
``opusenc`` for the *Opus* files. Consult corresponding encoder man pages for
details.
Usage
=====
@@ -57,9 +61,10 @@ Given that there are couple of music files, simplest usage is as follows:
$ flac2ogg.py directory_of_music_files/*
All files from that directory will be encoded to *ogg* by defaults. If there
are already some *ogg* files, new files would have ``_encoded_`` added into the
filename. Note, that output files will be placed next to the original files.
All files from that directory will be encoded to *opus* by default. If there
are already some *opus* files, new files would have ``_encoded_`` added into
the filename. Note, that output files will be placed next to the original
files.
License
=======
@@ -69,6 +74,7 @@ This work is licensed on 3-clause BSD license. See LICENSE file for details.
.. _mutagen: https://mutagen.readthedocs.io/en/latest/
.. _vorbis tools: http://www.vorbis.com/
.. _opus tools: https://opus-codec.org
.. _flac: http://www.vorbis.com/
.. _lame: http://lame.sourceforge.net/
.. _mac: http://www.deb-multimedia.org/dists/testing/main/binary-amd64/package/monkeys-audio.php
+40 -15
View File
@@ -14,7 +14,7 @@ from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3, EasyID3KeyError
VERSION = '1.2'
VERSION = '1.3'
def match_file(path):
@@ -129,8 +129,8 @@ class OggEncoder(Encoder):
self.quality = 8
def encode(self, input_fname, output_fname):
sp.check_call(["oggenc", "-q%s" % self.quality, input_fname,
'-o', output_fname])
sp.check_call(["oggenc", f"-q{self.quality}", input_fname, '-o',
output_fname])
class Mp3Encoder(Encoder):
@@ -144,7 +144,21 @@ class Mp3Encoder(Encoder):
self.quality = 6
def encode(self, input_fname, output_fname):
sp.check_call(["lame", "-V%s" % self.quality, input_fname,
sp.check_call(["lame", f"-V{self.quality}", input_fname, output_fname])
class OpusEncoder(Encoder):
"""Opus encoder"""
EXT = ".opus"
def __init__(self, quality=None):
"""Init"""
super().__init__(quality)
if self.quality is None:
self.quality = 128
def encode(self, input_fname, output_fname):
sp.check_call(["opusenc", "--bitrate", self.quality, input_fname,
output_fname])
@@ -288,7 +302,7 @@ class M4aType(FileType):
if "," in wav:
wav = wav.replace(",", "\\,")
sp.check_call(["mplayer", "-vo", "none", self.filename, "-ao",
"pcm:file=%s" % wav])
f"pcm:file={wav}"])
class WavType(FileType):
@@ -330,10 +344,18 @@ class OggType(FileType):
"""Ogg Vorbis filetype"""
def extract_wav(self):
"""Extract mp3 file to wav"""
"""Extract ogg vorbis file to wav"""
sp.check_call(["oggdec", self.filename])
class OpusType(FileType):
"""Opus filetype"""
def extract_wav(self):
"""Extract opus file to wav"""
sp.check_call(["opusdec", self.filename])
class Converter:
"""Main class for converting files"""
extract_map = {'.ape': ApeType,
@@ -342,6 +364,7 @@ class Converter:
'.mp3': Mp3Type,
'.mpc': MusepackType,
'.ogg': OggType,
'.opus': OpusType,
'.wav': WavType,
'.wv': WvType}
@@ -381,11 +404,11 @@ class Converter:
base + ".wv.cue", base + ".ape.cue"):
if os.path.exists(tmp):
cuefile = tmp
print("*** cuefile: %s" % cuefile)
print(f"*** cuefile: {cuefile}")
break
if cuefile is None:
print("*** No cuefile found for `%s'" % filename)
print(f"*** No cuefile found for `{filename}'")
return
cue = CueObjectParser(cuefile)
@@ -394,7 +417,7 @@ class Converter:
# list of wavs to encode
klass = Converter.extract_map.get(ext.lower())
if not klass:
print("*** Cannot find right converter for `%s'" % ext)
print(f"*** Cannot find right converter for `{ext}'")
return
fobj = klass(filename, encoder)
@@ -425,7 +448,8 @@ class Converter:
ENCODERS = {'ogg': OggEncoder,
'mp3': Mp3Encoder}
'mp3': Mp3Encoder,
'opus': OpusEncoder}
def main():
@@ -436,12 +460,13 @@ def main():
help='Split output file with provided *.cue file')
arg.add_argument('-r', '--recursive', action='store_true',
help='Do the files searching recursive')
arg.add_argument('-e', '--encoder', default='ogg', type=str,
choices=('ogg', 'mp3'), help='Encoder to use. Defaults '
'to "ogg"')
arg.add_argument('-e', '--encoder', default='opus', type=str,
choices=('ogg', 'mp3', 'opus'),
help='Encoder to use. Defaults to "opus"')
arg.add_argument('-q', '--quality', help='Quality of the encoded file. '
'Consult "lame" and "oggenc" for details. Defaults are '
'6 for lame and 8 for oggenc.')
'Consult "lame", "oggenc" and "opusenc" manuals for '
'details. Defaults are -V6 for lame, -q8 for oggenc and '
'--bitrate 128 for opusenc')
arg.add_argument('-v', '--version', action='version',
version='%(prog)s v' + VERSION,
help='Display version and exit.')