summaryrefslogtreecommitdiff
path: root/formats
diff options
context:
space:
mode:
Diffstat (limited to 'formats')
-rw-r--r--formats/__base__.py25
-rw-r--r--formats/__init__.py24
-rw-r--r--formats/flac.py39
-rw-r--r--formats/mp3.py49
4 files changed, 137 insertions, 0 deletions
diff --git a/formats/__base__.py b/formats/__base__.py
new file mode 100644
index 0000000..4bb6598
--- /dev/null
+++ b/formats/__base__.py
@@ -0,0 +1,25 @@
+class BaseHandler:
+ def __init__(self, logger = None):
+ self.logger = logger
+ self.buf = []
+
+ def log(self, fmt, *args):
+ if self.logger is not None:
+ self.logger(fmt, *args)
+
+ def add(self, *args):
+ self.buf.extend(args)
+
+ def build(self, join=True):
+ data = " ".join(self.buf) if join else self.buf
+ self.buf = []
+
+ return data
+
+ def add_sox_args(self, opt, info):
+ if opt.sample_rate and opt.sample_rate != info.sample_rate:
+ self.add("-r %d" % opt.sample_rate)
+ if opt.bits_per_sample and opt.bits_per_sample != info.bits_per_sample:
+ self.add("-b %d" % opt.bits_per_sample)
+ if opt.channels and opt.channels != info.channels:
+ self.add("-c %d" % opt.channels)
diff --git a/formats/__init__.py b/formats/__init__.py
new file mode 100644
index 0000000..7ebd9fd
--- /dev/null
+++ b/formats/__init__.py
@@ -0,0 +1,24 @@
+import importlib
+import os
+
+path = os.path.dirname(__file__) or "."
+
+__formats = {}
+
+for entry in sorted(os.listdir(path)):
+ if not entry.endswith(".py") or entry.startswith("_"):
+ continue
+
+ modname = entry.replace(".py", "")
+ mod = __import__(modname, globals(), locals(), ["init"], 1)
+ fmt = mod.init()
+ __formats[fmt.name] = fmt
+
+def supported():
+ return sorted(__formats.keys())
+
+def issupported(name):
+ return name in __formats
+
+def handler(name, logger = None):
+ return __formats.get(name)(logger)
diff --git a/formats/flac.py b/formats/flac.py
new file mode 100644
index 0000000..258b122
--- /dev/null
+++ b/formats/flac.py
@@ -0,0 +1,39 @@
+from formats.__base__ import *
+from utils import to_bytes
+
+import subprocess
+
+class FlacHandler(BaseHandler):
+ name = "flac"
+ ext = "flac"
+
+ def encode(self, opt, info):
+ self.add("flac sox -")
+
+ if opt.compression is not None:
+ self.add("-C %d" % opt.compression)
+
+ self.add_sox_args(opt, info)
+ self.add("%f")
+
+ return self.build()
+
+ def tag(self, path, tags):
+ args = ["metaflac", "--remove-all-tags", "--import-tags-from=-", path]
+ self.log("Tag [%s] : ", path)
+
+ proc = subprocess.Popen(args, stdin = subprocess.PIPE)
+ for k, v in tags.items():
+ if v is not "":
+ proc.stdin.write(to_bytes("%s=%s\n" % (k.upper(), v)))
+ proc.stdin.close()
+
+ if proc.wait():
+ self.log("FAILED\n")
+ return False
+
+ self.log("OK\n")
+ return True
+
+def init():
+ return FlacHandler
diff --git a/formats/mp3.py b/formats/mp3.py
new file mode 100644
index 0000000..0c91911
--- /dev/null
+++ b/formats/mp3.py
@@ -0,0 +1,49 @@
+from formats.__base__ import *
+from utils import to_bytes
+
+import subprocess
+
+class Mp3Handler(BaseHandler):
+ name = "mp3"
+ ext = "mp3"
+
+ __tag_opts = {
+ "album": "-a",
+ "artist": "-A",
+ "date": "-y",
+ "title": "-t"
+ }
+
+ def encode(self, opt, info):
+ self.add("cust ext=%s sox -" % self.ext)
+
+ if opt.bitrate is not None:
+ self.add("-C %d" % opt.bitrate)
+
+ self.add_sox_args(opt, info)
+ self.add("%f")
+
+ return self.build()
+
+ def tag(self, path, tags):
+ self.add("id3v2", "--id3v1-only")
+
+ for k, v in tags.items():
+ if k in self.__tag_opts and v:
+ self.add(self.__tag_opts[k])
+ self.add(v)
+
+ self.add("-T", "%d/%d" % (tags["tracknumber"], tags["tracktotal"]))
+ self.add(path)
+
+ self.log("Tag [%s] : ", path)
+
+ if subprocess.call(self.build(False)):
+ self.log("FAILED\n")
+ return False
+
+ self.log("OK\n")
+ return True
+
+def init():
+ return Mp3Handler