aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emms-player-mpd.el173
-rw-r--r--emms-playlist-mode.el3
2 files changed, 120 insertions, 56 deletions
diff --git a/emms-player-mpd.el b/emms-player-mpd.el
index 9ef3431..aae89dd 100644
--- a/emms-player-mpd.el
+++ b/emms-player-mpd.el
@@ -553,29 +553,32 @@ info from MusicPD."
(string-to-number (match-string 1 time)))))
"time" info)))
-(defun emms-player-mpd-sync-from-emms-1 (closure id)
- (let ((buffer (car closure))
- (fn (cadr closure))
- (close (cddr closure)))
- (when (buffer-live-p buffer)
- (with-current-buffer buffer
- (setq emms-player-mpd-playlist-id id))
- (when (functionp fn)
- (funcall fn close)))))
+(defun emms-player-mpd-sync-from-emms-1 (closure)
+ (emms-player-mpd-get-playlist-id
+ closure
+ (lambda (closure id)
+ (let ((buffer (car closure))
+ (fn (cdr closure)))
+ (funcall fn buffer id)))))
-(defun emms-player-mpd-sync-from-emms (&optional closure callback)
+(defun emms-player-mpd-sync-from-emms (callback)
"Synchronize the MusicPD playlist with the contents of the
current EMMS playlist.
-If CALLBACK is provided, call it with CLOSURE once we are done."
+
+If CALLBACK is provided, call it with the current EMMS playlist
+buffer and MusicPD playlist ID when we are done, if there were no
+errors."
(emms-player-mpd-clear)
(with-current-emms-playlist
- (save-excursion
- (mapc #'emms-player-mpd-add
- (nreverse
- (emms-playlist-tracks-in-region (point-min) (point-max)))))
- (emms-player-mpd-get-playlist-id
- (cons (current-buffer) (cons callback closure))
- #'emms-player-mpd-sync-from-emms-1)))
+ (let (tracks)
+ (save-excursion
+ (setq tracks (nreverse
+ (emms-playlist-tracks-in-region
+ (point-min) (point-max)))))
+ (emms-player-mpd-add-several-tracks
+ tracks
+ (cons (current-buffer) callback)
+ #'emms-player-mpd-sync-from-emms-1))))
(defun emms-player-mpd-sync-from-mpd-2 (closure info)
(let ((buffer (car closure))
@@ -660,7 +663,7 @@ info from MusicPD."
(defun emms-player-mpd-get-filename (file)
"Turn FILE into something that MusicPD can understand.
This usually means removing a prefix."
- (if (or (null emms-player-mpd-music-directory)
+ (if (or (not emms-player-mpd-music-directory)
(not (eq (aref file 0) ?/))
(string-match "\\`http://" file))
file
@@ -674,8 +677,6 @@ This usually means removing a prefix."
(emms-replace-regexp-in-string "\\\\" "\\\\\\\\" file))
"\""))
-;;; MusicPD commands
-
(defun emms-player-mpd-clear ()
"Clear the playlist."
(when emms-player-mpd-status-timer
@@ -683,48 +684,106 @@ This usually means removing a prefix."
(setq emms-player-mpd-status-timer nil))
(emms-player-mpd-send "clear" nil #'ignore))
-(defun emms-player-mpd-add-file (file)
+;;; Adding to the MusicPD playlist
+
+(defun emms-player-mpd-add-file (file closure callback)
"Add FILE to the current MusicPD playlist.
-If an error occurs, display a relevant message."
+If an error occurs, display a relevant message.
+
+Execute CALLBACK with CLOSURE as its first argument when done."
(setq file (emms-player-mpd-get-filename file))
(emms-player-mpd-send
(concat "add " (emms-player-mpd-quote-file file))
- file
- (lambda (file response)
- (let ((output (emms-player-mpd-parse-response response)))
- (when (car output)
- (message "MusicPD error: %s: %s" file (cdar output)))))))
-
-(defun emms-player-mpd-add-playlist (playlist)
+ (cons file (cons callback closure))
+ (lambda (closure response)
+ (let ((output (emms-player-mpd-parse-response response))
+ (file (car closure))
+ (callback (cadr closure))
+ (close (cddr closure)))
+ (if (car output)
+ (message "MusicPD error: %s: %s" file (cdar output))
+ (when (functionp callback)
+ (funcall callback close)))))))
+
+(defun emms-player-mpd-add-buffer-contents (closure callback)
+ "Load contents of the current buffer into MusicPD by adding each line.
+This handles both m3u and pls type playlists.
+
+Execute CALLBACK with CLOSURE as its first argument when done."
+ (goto-char (point-min))
+ (let ((format (emms-source-playlist-determine-format)))
+ (when format
+ (emms-player-mpd-add-several-files
+ (emms-source-playlist-files format)
+ closure callback))))
+
+(defun emms-player-mpd-add-playlist (playlist closure callback)
"Load contents of PLAYLIST into MusicPD by adding each line.
-This handles both m3u and pls type playlists."
+This handles both m3u and pls type playlists.
+
+Execute CALLBACK with CLOSURE as its first argument when done."
;; This is useful for playlists of playlists
(with-temp-buffer
(insert-file-contents playlist)
- (goto-char (point-min))
- (let ((format (emms-source-playlist-determine-format)))
- (when format
- (let ((list (emms-source-playlist-files format)))
- (dolist (file list)
- (emms-player-mpd-add-file file)))))))
-
-(defun emms-player-mpd-add (track)
- "Add TRACK to the MusicPD playlist."
+ (emms-player-mpd-add-buffer-contents closure callback)))
+
+(defun emms-player-mpd-add-streamlist (url closure callback)
+ "Download contents of URL and then add its feeds into MusicPD.
+
+Execute CALLBACK with CLOSURE as its first argument when done."
+ ;; This is useful with emms-streams.el
+ (condition-case nil
+ (progn
+ (require 'url)
+ (with-temp-buffer
+ (url-insert-file-contents url)
+ (emms-player-mpd-add-buffer-contents closure callback)))
+ (error (message (concat "You need to install url.el so that"
+ " Emms can retrieve this stream")))))
+
+(defun emms-player-mpd-add (track closure callback)
+ "Add TRACK to the MusicPD playlist.
+
+Execute CALLBACK with CLOSURE as its first argument when done."
(let ((name (emms-track-get track 'name))
(type (emms-track-get track 'type)))
(cond ((eq type 'url)
- (emms-player-mpd-add-file name))
+ (emms-player-mpd-add-file name closure callback))
+ ((eq type 'streamlist)
+ (emms-player-mpd-add-streamlist name closure callback))
((or (eq type 'playlist)
(string-match "\\.\\(m3u\\|pls\\)\\'" name))
- (emms-player-mpd-add-playlist name))
+ (emms-player-mpd-add-playlist name closure callback))
((eq type 'file)
- (emms-player-mpd-add-file name)))))
+ (emms-player-mpd-add-file name closure callback)))))
+
+(defun emms-player-mpd-add-several-tracks (tracks closure callback)
+ "Add TRACKS to the MusicPD playlist.
+
+Execute CALLBACK with CLOSURE as its first argument when done."
+ (when (consp tracks)
+ (while (cdr tracks)
+ (emms-player-mpd-add (car tracks) nil #'ignore)
+ (setq tracks (cdr tracks)))
+ ;; only execute callback on last track
+ (emms-player-mpd-add (car tracks) closure callback)))
+
+(defun emms-player-mpd-add-several-files (files closure callback)
+ "Add FILES to the MusicPD playlist.
+
+Execute CALLBACK with CLOSURE as its first argument when done."
+ (when (consp files)
+ (while (cdr files)
+ (emms-player-mpd-add-file (car files) nil #'ignore)
+ (setq files (cdr files)))
+ ;; only execute callback on last file
+ (emms-player-mpd-add-file (car files) closure callback)))
;;; EMMS API
(defun emms-player-mpd-playable-p (track)
"Return non-nil when we can play this track."
- (and (memq (emms-track-type track) '(file url playlist))
+ (and (memq (emms-track-type track) '(file url playlist streamlist))
(string-match (emms-player-get emms-player-mpd 'regex)
(emms-track-name track))))
@@ -751,13 +810,14 @@ playlist."
(lambda (closure response)
(emms-player-started 'emms-player-mpd)))))
-(defun emms-player-mpd-start-and-sync-1 (buffer)
+(defun emms-player-mpd-start-and-sync-1 (buffer id)
(when emms-player-mpd-status-timer
(emms-cancel-timer emms-player-mpd-status-timer)
(setq emms-player-mpd-status-timer nil))
(when (buffer-live-p buffer)
(let ((emms-playlist-buffer buffer))
(with-current-emms-playlist
+ (setq emms-player-mpd-playlist-id id)
(emms-player-mpd-play (1- (emms-line-number-at-pos
emms-playlist-selected-marker)))))))
@@ -771,9 +831,8 @@ This is called if `emms-player-mpd-sync-playlist' is non-nil."
(lambda (closure id)
(if (and (stringp emms-player-mpd-playlist-id)
(string= emms-player-mpd-playlist-id id))
- (emms-player-mpd-start-and-sync-1 emms-playlist-buffer)
+ (emms-player-mpd-start-and-sync-1 emms-playlist-buffer id)
(emms-player-mpd-sync-from-emms
- emms-playlist-buffer
#'emms-player-mpd-start-and-sync-1)))))
(defun emms-player-mpd-connect-1 (closure info)
@@ -803,12 +862,13 @@ Afterward, the status of MusicPD will be tracked."
(defun emms-player-mpd-start (track)
"Starts a process playing TRACK."
(interactive)
- (if emms-player-mpd-sync-playlist
+ (if (and emms-player-mpd-sync-playlist
+ (not (memq (emms-track-get track 'type) '(streamlist playlist)))
+ (not (string-match "\\`http://" (emms-track-get track 'name))))
(emms-player-mpd-start-and-sync)
(emms-player-mpd-clear)
- (when (emms-player-mpd-add track)
- ;; if we have loaded the item successfully, play it
- (emms-player-mpd-play))))
+ ;; if we have loaded the item successfully, play it
+ (emms-player-mpd-add track nil #'emms-player-mpd-play)))
(defun emms-player-mpd-disconnect (&optional no-stop)
"Terminate the MusicPD client process and disconnect from MusicPD.
@@ -887,12 +947,15 @@ positive or negative."
(insertp (car closure))
(callback (cadr closure))
(buffer (cddr closure))
+ (name (cdr (assoc "name" info)))
(desc nil))
(when info
- (emms-track-set track 'type 'file)
- (emms-track-set track 'name (cdr (assoc "file" info)))
- (emms-info-mpd track info)
- (setq desc (emms-track-description track)))
+ (if name
+ (setq desc name)
+ (emms-track-set track 'type 'file)
+ (emms-track-set track 'name (cdr (assoc "file" info)))
+ (emms-info-mpd track info)
+ (setq desc (emms-track-description track))))
(if (not desc)
(message "Nothing playing right now")
(setq desc (format emms-show-format desc))
diff --git a/emms-playlist-mode.el b/emms-playlist-mode.el
index b35e9b3..88f36c7 100644
--- a/emms-playlist-mode.el
+++ b/emms-playlist-mode.el
@@ -190,7 +190,8 @@ Otherwise play the track immediately."
(name (emms-track-get track 'name))
(type (emms-track-get track 'type)))
(if (or (eq type 'playlist)
- (string-match "\\.\\(m3u\\|pls\\)\\'" name))
+ (and (eq type 'file)
+ (string-match "\\.\\(m3u\\|pls\\)\\'" name)))
(emms-playlist-mode-load-playlist)
(emms-playlist-mode-play-current-track)))))