616d183eeef528d7b132a7feef515698b5b8e603
[emus.git] / emus.el
1 ;;; emus.el --- Simple music player for Emacs.  -*- lexical-binding:t -*-
2
3 ;; Author: Tim Vaughan <timv@ughan.xyz>
4 ;; Version: 1.0
5 ;; Keywords: multimedia
6 ;; URL: http://github.com/tgvaughan/emus
7
8 ;;; Commentary:
9
10 ;; This is a simple package for playing audio from a local library
11 ;; of audio files.
12
13 ;;; Code:
14
15 ;;; Customizations
16 ;;
17
18 (defgroup emus nil
19   "Simple music player for Emacs inspired by CMUS."
20   :group 'multimedia)
21
22 (defcustom emus-directory "~/Music/"
23   "Directory containing audio files for emus."
24   :type '(string))
25
26 (defcustom emus-mpg123-program "mpg123"
27   "Name of (and, optionally, path to) mpg123 binary."
28   :type '(string))
29
30 ;;; Library
31 ;;
32
33 (defvar emus-library nil
34   "Emus audio library.")
35
36 (defun emus-get-audio-files ()
37   "Get all mp3 files in main emus directory."
38   (directory-files-recursively emus-directory ".*\\.mp3"))
39
40 (defvar emus-tags nil)
41
42 (defun emus-update-tags ()
43   "Get ID3 tags for given filename"
44   (let ((proc (emus-get-process))
45         (depth 0)
46         (tagstr "")
47         (filenames (emus-get-audio-files)))
48     (setq emus-tags nil)
49     (set-process-filter proc (lambda (proc string)
50                                (setq tagstr (concat tagstr string))
51                                (cond
52                                 ((string-suffix-p "}\n" string) (setq depth (- depth 1)))
53                                 ((string-suffix-p "{\n" string) (setq depth (+ depth 1))))
54                                (when (and (= depth 0) (string-suffix-p "\n" string))
55                                  (add-to-list 'emus-tags `(,(car filenames) ,tagstr))
56                                  (setq tagstr "")
57                                  (setq filenames (cdr filenames))
58                                  (if filenames
59                                      (emus-send-cmd "lp" (car filenames))
60                                    (set-process-filter proc nil)))))
61     (emus-send-cmd "lp" (car filenames))))
62
63 (defun emus-get-process ()
64   "Return current or new mpg123 process."
65   (let* ((emus-process-raw (get-process "emus-process"))
66          (emus-process (if emus-process-raw
67                            (if (process-live-p emus-process-raw)
68                                emus-process-raw
69                              (kill-process emus-process-raw)
70                              nil))))
71     (if emus-process
72         emus-process
73       (make-process :name "emus-process"
74                     ;; :buffer (get-buffer-create "*emus-process*")
75                     :command `(,emus-mpg123-program "-R")))))
76
77 (defun emus-send-cmd (cmd &rest args)
78   (process-send-string (emus-get-process)
79                        (concat
80                         (seq-reduce (lambda (s1 s2) (concat s1 " " s2)) args cmd)
81                         "\n")))
82
83 ;;; Browser
84 ;;
85
86 (defun emus-browse ()
87   "Switch to *emus* audio library browser."
88   (interactive)
89   (switch-to-buffer "*emus*")
90   (emus-mode))
91
92 (define-derived-mode emus-mode special-mode "Emus"
93   "Major mode for EMUS music player.")
94
95 ;;; Debugging
96
97 (defun emus-test ()
98   (message (emus-get-file-tags "/Users/vaughant/Music/Floex_-_Zorya/Floex - Zorya - 01 Ursa Major.mp3")))
99
100 (defun emus-test-play ()
101   (emus-send-cmd "lp" "/Users/vaughant/Music/Floex_-_Zorya/Floex - Zorya - 01 Ursa Major.mp3")
102   (emus-send-cmd "silence")
103   (emus-send-cmd "p"))
104
105
106 ;;; emus.el ends here