emms-help
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add: tracktag interface and support for Opus


From: Grant Shoshin Shangreaux
Subject: [PATCH] Add: tracktag interface and support for Opus
Date: Fri, 07 May 2021 16:15:51 -0500

Here's a patch I've been using locally to tag Opus files. It could
certainly use some more quality assurance, it works for me but it hasn't
been used very extensively. This wraps the `tracktag` executable from
the `audiotools` package http://audiotools.sourceforge.net/index.html
which should be available in GNU/Linux repositories. I am running PureOS
backed by Debian and it is available to me through apt. It might be
useful to find out if it can be easily installed on other
platforms. Unfortunately, it does not look to be available for homebrew
on MacOS, and I'm really not sure about Windows. This is too bad, since
an easily installed, multi-format tagger is part of the reason I went
with this tool.

I've also added a very naive setup for running ERT tests, any feedback
there would be welcome. I will say, it was pretty useful for me while
developing, but YMMV.

By the way, I used some real metadata from tracks I have, but afaik that
is not copyrighted data. If we'd prefer to keep it out of the code base,
I can replace it. If I add any audio files in for testing, I will ensure
they are properly free. My plan was to just generate some very small
files of silence in several formats. Whether or not this is useful for
testing before a release is up for discussion.

I hope this is useful!

-Grant

>From c80315946e885a523f74d6a66ca7d7fa0682d6c2 Mon Sep 17 00:00:00 2001
From: Grant Shangreaux <grant@unabridgedsoftware.com>
Date: Sun, 10 Jan 2021 20:30:35 -0600
Subject: [PATCH] Add: emms-tracktag wrapper for the audiotools program

http://audiotools.sourceforge.net/ provides a tool `tracktag`
which handles writing tags for several different audio formats,
including Opus. this patch provides a very basic wrapper to interface
between EMMS track info and tracktag metadata. It also configures
emms-tag-editor.el to use it for writing tags to Opus files.

Add: test.sh and test/test-all.el

Basic setup to run ert tests from the terminal using Emacs in batch
mode. This should load up only ERT, the tests in the test/ directory
and their dependencies.

Add: opus extension to emms-libtag-known-extensions

libtag works as a reader for opus files, this just ads the opus
extension to the regexp list.
---
 emms-info-libtag.el        |   2 +-
 emms-tag-editor.el         |   4 +-
 emms-tracktag.el           |  71 ++++++++++++++++++++++++++
 test.sh                    |   3 ++
 test/emms-tracktag-test.el | 101 +++++++++++++++++++++++++++++++++++++
 test/test-all.el           |   6 +++
 6 files changed, 185 insertions(+), 2 deletions(-)
 create mode 100644 emms-tracktag.el
 create mode 100755 test.sh
 create mode 100644 test/emms-tracktag-test.el
 create mode 100644 test/test-all.el

diff --git a/emms-info-libtag.el b/emms-info-libtag.el
index fb9c5dd..9425a38 100644
--- a/emms-info-libtag.el
+++ b/emms-info-libtag.el
@@ -74,7 +74,7 @@
   :type '(string))
 
 (defcustom emms-info-libtag-known-extensions
-  (regexp-opt '("mp3" "mp4" "m4a" "ogg" "flac" "spx" "wma"))
+  (regexp-opt '("mp3" "mp4" "m4a" "ogg" "flac" "spx" "wma" "opus"))
   "Regexp of known extensions compatible with `emms-info-libtag-program-name'.
 
 Case is irrelevant."
diff --git a/emms-tag-editor.el b/emms-tag-editor.el
index 5b6e447..45c90f7 100644
--- a/emms-tag-editor.el
+++ b/emms-tag-editor.el
@@ -37,6 +37,7 @@
 (require 'emms-info-mp3info)
 (require 'emms-playlist-mode)
 (require 'emms-mark)
+(require 'emms-tracktag)
 (require 'format-spec)
 (require 'subr-x)
 
@@ -138,7 +139,8 @@ See also `emms-tag-editor-default-parser'.")
       (info-performer   . "--TOPE")
       (info-date        . "--TDAT")))
     ("ogg" . emms-tag-editor-tag-ogg)
-    ("flac" . emms-tag-editor-tag-flac))
+    ("flac" . emms-tag-editor-tag-flac)
+    ("opus" . emms-tracktag-file))
   "An alist used when committing changes to tags in files.
 If the external program sets tags by command line options
 one-by-one, then the list should like:
diff --git a/emms-tracktag.el b/emms-tracktag.el
new file mode 100644
index 0000000..0b8b660
--- /dev/null
+++ b/emms-tracktag.el
@@ -0,0 +1,71 @@
+;;; emms-tracktag.el --- EMMS interface for audiotools tracktag  -*- 
lexical-binding: t; -*-
+
+;; Copyright (C) 2021  Grant Shoshin Shangreaux
+
+;; Author: Grant Shoshin Shangreaux <grant@churls.world>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides a wrapper for audiotools tracktag executable
+;; http://audiotools.sourceforge.net/tracktag.html
+;; Given an EMMS TRACK structure, it will map the emms-info fields onto
+;; arguments for tracktag. Then it calls the tracktag process to write the
+;; info as metadata tags on the track's associated file.
+
+;;; Code:
+
+(require 'emms)
+
+(defvar emms-info-tracktag--info-fields
+  '((info-album . album)
+    (info-artist . artist)
+    (info-composer . composer)
+    (info-performer . performer)
+    (info-year . year)
+    (info-date . year)
+    (info-tracknumber . number)
+    (info-discnumber . album-number)
+    (info-note . comment)
+    (info-title . name))
+  "An alist mapping info-* fields to tracktag fields.")
+
+(defun emms-tracktag--map-track-info (track)
+  (seq-filter (lambda (cell) (cdr cell))
+              (mapcar (lambda (pair)
+                        (cons (cdr pair) (emms-track-get track (car pair))))
+                      emms-info-tracktag--info-fields)))
+
+(defun emms-tracktag--build-args (track)
+  (flatten-list
+   (append (mapcar (lambda (pair)
+                     (let ((tag (car pair)) (value (cdr pair)))
+                       (when value
+                         (if (string-equal value "") (concat "--remove-" 
(format "%s" tag))
+                           (concat "--" (format "%s" tag) "=" value)))))
+                   (emms-tracktag--map-track-info track))
+           (list (emms-track-name track)))))
+
+(defun emms-tracktag-file (track)
+  (apply #'call-process
+   "tracktag" nil
+   (get-buffer-create emms-tag-editor-log-buffer)
+   nil
+   "-Vdebug"
+   (emms-tracktag--build-args track)))
+
+(provide 'emms-tracktag)
+;;; emms-tracktag.el ends here
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..50547b1
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+emacs -Q --batch --directory="." -l ert -l test/test-all.el -f 
ert-run-tests-batch-and-exit
diff --git a/test/emms-tracktag-test.el b/test/emms-tracktag-test.el
new file mode 100644
index 0000000..9b66d5e
--- /dev/null
+++ b/test/emms-tracktag-test.el
@@ -0,0 +1,101 @@
+;; emms-tracktag-test.el --- Unit tests for emms-tracktag module  -*- 
lexical-binding: t; -*-
+
+;; Copyright (C) 2021  Grant Shoshin Shangreaux
+
+;; Author: Grant Shoshin Shangreaux <grant@churls.world>
+;; Keywords:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for emms-tracktag.el
+
+;;; Code:
+
+(require 'emms)
+(require 'emms-tracktag)
+
+(ert-deftest emms-tracktag--map-track-info-test ()
+  "Ensure mapping of emms info to tracktag fields is correct."
+  (let ((track '(*track*
+                 (type . file) (name . "foo")
+                 (info-album . "The Sounds of the Sounds of Science")
+                 (info-artist . "Yo La Tengo")
+                 (info-title . "Sea Urchins")
+                 (info-date . "2020")
+                 (info-tracknumber . "1")))
+        (track2 '(*track*
+                  (info-composer . "Ira Kaplan, Georgia Hubley, James Mcnew")
+                  (info-performer . "Yo La Tengo")
+                  (info-year . "2002")
+                  (info-discnumber . "1")
+                  (info-note . "new soundtrack to an old film"))))
+    (should (seq-set-equal-p
+             '((album . "The Sounds of the Sounds of Science")
+               (artist . "Yo La Tengo")
+               (name . "Sea Urchins")
+               (year . "2020")
+               (number . "1"))
+             (emms-tracktag--map-track-info track)))
+    (should (seq-set-equal-p
+             '((composer . "Ira Kaplan, Georgia Hubley, James Mcnew")
+               (performer . "Yo La Tengo")
+               (year . "2002")
+               (album-number . "1")
+               (comment . "new soundtrack to an old film"))
+             (emms-tracktag--map-track-info track2)))))
+
+(ert-deftest emms-tracktag--build-args-test ()
+  "Ensure args for tracktag are properly formed."
+  (let ((track '(*track*
+                 (type . file) (name . "foo.flac")
+                 (info-album . "The Sounds of the Sounds of Science")
+                 (info-artist . "Yo La Tengo")
+                 (info-title . "Sea Urchins")
+                 (info-date . "2020")
+                 (info-tracknumber . "1")
+                 (info-composer . "Ira Kaplan, Georgia Hubley, James Mcnew")
+                 (info-performer . "Yo La Tengo")
+                 (info-discnumber . "1")
+                 (info-note . "new soundtrack to an old film"))))
+    (should (seq-set-equal-p
+             '("--album=The Sounds of the Sounds of Science"
+               "--artist=Yo La Tengo"
+               "--name=Sea Urchins"
+               "--year=2020"
+               "--number=1"
+               "--composer=Ira Kaplan, Georgia Hubley, James Mcnew"
+               "--performer=Yo La Tengo"
+               "--album-number=1"
+               "--comment=new soundtrack to an old film"
+               "foo.flac")
+             (emms-tracktag--build-args track)))
+    (let ((track-with-empty-strings (copy-alist track)))
+      (setcdr (assq 'info-title track-with-empty-strings) "")
+      (setcdr (assq 'info-note track-with-empty-strings) "")
+      (should (seq-set-equal-p
+               '("--album=The Sounds of the Sounds of Science"
+                 "--artist=Yo La Tengo"
+                 "--year=2020"
+                 "--number=1"
+                 "--composer=Ira Kaplan, Georgia Hubley, James Mcnew"
+                 "--performer=Yo La Tengo"
+                 "--album-number=1"
+                 "--remove-comment"
+                 "--remove-name"
+                 "foo.flac")
+               (emms-tracktag--build-args track-with-empty-strings))))))
+
+;;; emms-tracktag-test.el ends here
diff --git a/test/test-all.el b/test/test-all.el
new file mode 100644
index 0000000..36f00c7
--- /dev/null
+++ b/test/test-all.el
@@ -0,0 +1,6 @@
+;; maybe not needed, but ensures tests run against the latest changes
+(byte-recompile-directory ".")
+
+(mapc #'load
+      (mapcar (lambda (f) (file-truename (concat "test/" f)))
+              (seq-filter (lambda (f) (string-match "[^.#]+\\test.el$" f)) 
(directory-files (file-truename "./test")))))
-- 
2.20.1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]