diff options
author | yoni-r <yoni-r> | 2006-09-24 14:18:00 +0000 |
---|---|---|
committer | yoni-r <mwolson@gnu.org> | 2006-09-24 14:18:00 +0000 |
commit | 03bc583073b06d1f2b36c62227d8d0d59ea4aa36 (patch) | |
tree | d7a9b217d779aa32b4d6b37749b64b2d74ab54b2 | |
parent | f9e09deb8927418fafeafa42fb838ffad2e35c28 (diff) |
Added emms-bookmarks.el
darcs-hash:20060924141826-85c19-ac8a381dd9f8ddf8e0a9f2c358736bbcd55455f8.gz
-rw-r--r-- | emms-bookmarks.el | 147 | ||||
-rw-r--r-- | emms-setup.el | 1 |
2 files changed, 148 insertions, 0 deletions
diff --git a/emms-bookmarks.el b/emms-bookmarks.el new file mode 100644 index 0000000..fbd0195 --- /dev/null +++ b/emms-bookmarks.el @@ -0,0 +1,147 @@ +;;; emms-bookmarks.el --- Bookmarks for Emms. + +;; Copyright (C) 2006 Free Software Foundation, Inc. + +;; Author: Yoni Rabkin <yonirabkin@member.fsf.org> +;; Keywords: emms, bookmark + +;; This file is part of EMMS. + +;; EMMS 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 2, or (at your option) +;; any later version. +;; +;; EMMS 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 EMMS; if not, write to the Free Software Foundation, +;; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +;;; Commentary: +;; +;; You can use this to add "temporal bookmarks" (term by Lucas Bonnet) +;; into your media files. The interesting functions here are +;; `emms-bookmarks-next', `emms-bookmarks-prev', `emms-bookmarks-add' +;; (which pauses the player while you describe the bookmark) and +;; `emms-bookmarks-clear'. All of which do exactly what you think they +;; do. + +;;; Code: + + +;; dependencies +(require 'emms) +(require 'emms-playing-time) + +(defvar emms-bookmarks-prev-overshoot 5 + "Time in seconds for skipping a previous bookmark.") + +(defun emms-bookmarks-reset (track) + "Remove all the bookmarks from TRACK." + (emms-track-set track 'bookmarks nil)) + +(defun emms-bookmarks-straight-insertion-sort (item l acc) + "Insert ITEM into the already sorted L, ACC should be nil." + (if (null l) + (append acc (list item)) + (cond ((< (cdr item) (cdr (car l))) (append acc (list item (car l)) (cdr l))) + (t (emms-bookmarks-straight-insertion-sort item (cdr l) (append acc (list (car l)))))))) + +(defun emms-bookmarks-get (track) + "Return the bookmark property from TRACK." + (emms-track-get track 'bookmarks)) + +(defun emms-bookmarks-set (track desc time) + "Set bookmark property for TRACK, text DESC at TIME seconds." + (let ((old-bookmarks (emms-track-get track 'bookmarks)) + (new-bookmarks nil)) + (setq new-bookmarks (emms-bookmarks-straight-insertion-sort (cons desc time) old-bookmarks nil)) + (emms-track-set track 'bookmarks new-bookmarks))) + +(defun emms-bookmarks-set-current (desc) + "Set bookmark property for the current track with text DESC." + (emms-bookmarks-set (emms-playlist-current-selected-track) desc emms-playing-time)) + +(defun emms-bookmarks-search (time track test) + "Return a bookmark based on heuristics. + +TIME should be a reference point in seconds. +TRACK should be an Emms track. +TEST should be a numerical comparator predicate." + (let ((s (append (list (cons "time" time)) (copy-sequence (emms-bookmarks-get track))))) + (sort s #'(lambda (a b) (funcall test (cdr a) (cdr b)))) + (while (not (= time (cdar s))) + (setq s (cdr s))) + (when (cdr s) + (car (cdr s))))) + +(defun emms-bookmarks-next-1 (time track) + "Return the bookmark after TIME for TRACK, otherwise return nil." + (emms-bookmarks-search time track #'<)) + +(defun emms-bookmarks-prev-1 (time track) + "Return the bookmark before TIME for TRACK, otherwise return nil." + (emms-bookmarks-search (- time emms-bookmarks-prev-overshoot) track #'>)) + +(defun emms-bookmarks-goto (search-f track failure-message) + "Seek the player to a bookmark. + +SEARCH-F should be a function which returns a bookmark. +TRACK should be an Emms track. +FAILURE-MESSAGE should be a string." + ;; note that when emms is paused then `emms-player-playing-p' => t + (when (not emms-player-playing-p) + (emms-start)) + (let ((m (funcall search-f emms-playing-time track))) + (if m + (progn + (emms-player-seek-to (cdr m)) + (message (car m))) + (message failure-message)))) + + +;; entry points + +(defun emms-bookmarks-next () + "Seek to the next bookmark in the current track." + (interactive) + (emms-bookmarks-goto #'emms-bookmarks-next-1 + (emms-playlist-current-selected-track) + "No next bookmark")) + +(defun emms-bookmarks-prev () + "Seek to the previous bookmark in the current track." + (interactive) + (emms-bookmarks-goto #'emms-bookmarks-prev-1 + (emms-playlist-current-selected-track) + "No previous bookmark")) + +;; can't use `interactive' to promt the user here because we want to +;; pause the player before the prompt appears. +(defun emms-bookmarks-add () + "Add a new bookmark to the current track. + +This function pauses the player while promting the user for a +description of the bookmark. The function resumes the player +after the prompt." + (interactive) + (emms-pause) + (let ((desc (read-string "Description: "))) + (if (emms-playlist-current-selected-track) + (emms-bookmarks-set-current desc) + (error "No current track to bookmark"))) + (emms-pause)) + +(defun emms-bookmarks-clear () + "Remove all the bookmarks from the current track." + (interactive) + (let ((this (emms-playlist-current-selected-track))) + (when this (emms-bookmarks-reset this)))) + +(provide 'emms-bookmarks) + +;;; emms-bookmarks.el ends here diff --git a/emms-setup.el b/emms-setup.el index 06cda62..2fc650d 100644 --- a/emms-setup.el +++ b/emms-setup.el @@ -123,6 +123,7 @@ on the edge." (require 'emms-stream-info) (require 'emms-score) (require 'emms-last-played) + (require 'emms-bookmarks) ;; setup (add-hook 'emms-player-started-hook 'emms-last-played-update-current)) |