fordon_greeman / voidfiles

Branch: main
Switch branches/tags
main
theidioticdev add emacs 2079ec5 22h ago
111 lines · 3.3 KB Raw Blame History
1 ;;; emms-info-exiftool.el --- info-method for EMMS using exiftool -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2020, 2022, 2025 Free Software Foundation, Inc.
4
5 ;; Author: Yoni Rabkin (yrk@gnu.org)
6 ;; Keywords: multimedia
7
8 ;; EMMS is free software; you can redistribute it and/or modify it
9 ;; under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
12
13 ;; EMMS is distributed in the hope that it will be useful, but WITHOUT
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 ;; License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with EMMS; see the file COPYING.. If not, see
20 ;; <https://www.gnu.org/licenses/>.
21
22 ;;; Commentary:
23
24 ;; (setq emms-info-functions '(emms-info-exiftool))
25
26 ;; To use this you would need to have exiftool installed on your
27 ;; system.
28
29
30 ;;; Code:
31
32 (require 'emms-info)
33 (require 'json)
34
35
36 (defgroup emms-info-exiftool nil
37 "Options for EMMS."
38 :group 'emms-info)
39
40 (defvar emms-info-exiftool-field-map
41 '((info-album . Album)
42 (info-artist . Artist)
43 (info-title . Title)
44 (info-tracknumber . TrackNumber)
45 (info-composer . Composer)
46 (info-year . Year)
47 (info-discnumber . Discnumber)
48 (info-genre . Genre)
49 (info-note . Comment)
50 (info-playing-time . Duration)
51 (info-albumartist . Albumartist))
52 "Mapping for exiftool output.")
53
54
55 ;; should only be called inside a buffer containing the json output of
56 ;; exiftool
57 (defun emms-info-exiftool-time ()
58 "Convert from exiftool-time to seconds."
59 (save-excursion
60 (goto-char (point-min))
61 (if (re-search-forward "duration.+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)"
62 (point-max) t)
63 (let ((hours (string-to-number (match-string-no-properties 1)))
64 (minutes (string-to-number (match-string-no-properties 2)))
65 (seconds (string-to-number (match-string-no-properties 3))))
66 (+ (* hours 60 60)
67 (* minutes 60)
68 seconds))
69 0)))
70
71 (defun emms-info-exiftool (track)
72 "Set TRACK info using exiftool."
73 (when (eq (emms-track-type track) 'file)
74 (with-temp-buffer
75 (when (zerop
76 (let ((coding-system-for-read 'utf-8))
77 (call-process "exiftool" nil '(t nil) nil
78 "-json" (emms-track-name track))))
79 (goto-char (point-min))
80 (condition-case nil
81 (let ((json-fields (elt (json-read) 0)))
82 (mapc
83 (lambda (field-map)
84 (let ((emms-field (car field-map))
85 (exiftool-field (cdr field-map)))
86 (let ((track-field (assoc exiftool-field json-fields)))
87 (when track-field
88 (emms-track-set
89 track
90 emms-field
91 (cond ((eq emms-field 'info-playing-time)
92 (emms-info-exiftool-time))
93 ((memq emms-field '(info-album
94 info-artist
95 info-albumartist
96 info-composer
97 info-note
98 info-tracknumber
99 info-title
100 info-year
101 info-discnumber))
102 (format "%s" (cdr track-field)))
103 (t (cdr track-field))))))))
104 emms-info-exiftool-field-map))
105 (error (message "error while reading track info")))
106 track))))
107
108
109 (provide 'emms-info-exiftool)
110
111 ;;; emms-info-exiftool.el ends here