[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[emms-help] emms-lyric.el v0.1, emms+.el v0.2
From: |
William XWL |
Subject: |
[emms-help] emms-lyric.el v0.1, emms+.el v0.2 |
Date: |
Sun, 17 Jul 2005 21:32:28 +0800 |
User-agent: |
Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) |
Hi, all.
I've just written a emms-lyric.el, which allows you to play music and
display lyrics either on mode line or minibuffer synchronically.
And an update to emms+.el(renamed from emms-patch.el), which gives you
more user control level funtions, like pause, seek, repeat.
Anybody interested? :P
--
William
;; emms+.el - Add more user control functions for EMMS
;; Copyright (C) 2005 William XWL
;; Author: William XWL <address@hidden>
;; Version: v 0.2
;; Last updated: 2005/07/17 20:27:45
;; This file is not part of GNU Emacs.
;;{{{ GPL
;; 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 2, 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, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;;}}}
;;; Commentary:
;; 1. Add `emms-pause', `emms-seek' for emms-player-mplayer, this
;; requires passing `-slave' parameter to mplayer, i.e,
;;
;; (setq emms-player-mplayer-command-name "mplayer"
;; emms-player-mplayer-parameters '("-slave")
;; emms-player-list
;; '(emms-player-mplayer
;; emms-player-mplayer-playlist
;; emms-player-mpg321
;; emms-player-ogg123))
;;
;; 2. Add `emms-repeat-curr', `emms-unrepeat-curr', `emms-repeat-all',
;; `emms-unrepeat-all', `emms-set-repeat-curr-mark',
;; `emms-set-unrepeat-curr-mark', `emms-set-repeat-all-mark',
;; `emms-set-unrepeat-all-mark' to all existing players! When repeating,
;; an extra star '*'(repeat current track) or '**' (repeat all tracks)
;; will be inserted in front of the `emms-mode-line-string'. To achieve
;; this, i've added a new variable `emms-repeat-curr-track' and redefine
;; the function `emms-next-noerror'.
;;
;; 3. Use amixer.el to control volumes, which requires aumix installed,
;; and only works on Linux currently.
;;
;; To use, put this file to your load-path and the following(together
;; with your other emms's settings) to your .emacs:
;;
;; (require 'emms-patch)
;;; Change Log
;; v 0.2 [2005/07/17 20:22:53] And `emms-player-paused-p',
;; `emms-player-player-paused-hook', and some modifications to
;; cooperate with another package(`emms-lyric.el'). Rename this
;; file from emms-patch.el to emms+.el.
;; v 0.1 The initial version
;;; Todo:
;; Hopefully, this package will change synchronically with
;; `emms-lyric.el' for cooperation.
;;; Codes:
(require 'emms)
;; amixer(only for Linux, comment following parts to enable.
;; (require 'amixer)
;; (setq amixer-mixer-program "aumix"
;; amixer-volume-increment 1
;; amixer-master-volume 35)
;; (global-set-key (kbd "C-M-9") 'amixer-decrement-volume)
;; (global-set-key (kbd "C-M-0") 'amixer-increment-volume)
;; mplayer: pause, seek
(defvar emms-player-paused-p nil
"The EMMS player paused.")
(defvar emms-player-paused-hook nil
"*Hook run when an EMMS player pauses playing.")
(emms-player-set emms-player-mplayer
'pause
'emms-player-mplayer-pause)
(emms-player-set emms-player-mplayer
'seek
'emms-player-mplayer-seek)
(defun emms-player-mplayer-pause ()
"Depends on mplayer's -slave mode."
(process-send-string
emms-player-simple-process-name "pause\n")
(if emms-player-paused-p
(setq emms-player-paused-p nil)
(setq emms-player-paused-p t))
(run-hooks 'emms-player-paused-hook))
(defun emms-player-mplayer-seek (second)
"Depends on mplayer's -slave mode."
(process-send-string
emms-player-simple-process-name
(concat "seek " second "\n")))
(defun emms-pause ()
"Pause the current player."
(interactive)
(when emms-player-playing-p
(if (equal emms-player-playing-p
'emms-player-mplayer)
(funcall (emms-player-get emms-player-playing-p 'pause))
(message "Pause is only available for mplayer."))))
(defun emms-seek (second)
"Seek forward/backward."
(interactive)
(when emms-player-playing-p
(if (equal emms-player-playing-p
'emms-player-mplayer)
(funcall (emms-player-get emms-player-playing-p 'seek) second)
(message "Seek is only available for mplayer."))))
;; repeat(any player)
(mapcar '(lambda (player) ; set up
(mapcar* '(lambda (name value)
(emms-player-set player
name
value))
'(repeat-curr
unrepeat-curr
repeat-all
unrepeat-all)
'(emms-player-any-repeat-curr
emms-player-any-unrepeat-curr
emms-player-any-repeat-all
emms-player-any-unrepeat-curr)))
emms-player-list)
(setq emms-repeat-curr-track nil) ; *new* - repeat current track
(setq emms-repeat-playlist nil) ; repeat all tracks
(defun emms-next-noerror () ; redefine this function
"Start playing the next track in the EMMS playlist.
Unlike `emms-next', this function doesn't signal an error when called
at the end of the playlist.
This function should only be called when no player is playing.
This is a good function to put in `emms-player-finished-hook'."
(interactive)
(when emms-player-playing-p
(error "A track is already being played"))
(cond (emms-repeat-curr-track ; repeat current track only.
(emms-start))
((emms-playlist-next)
(emms-start))
(emms-repeat-playlist
(setq emms-playlist-current 0)
(emms-start))
(t
(message "No next track in playlist"))))
(defun emms-player-any-repeat-curr ()
(setq emms-repeat-curr-track t)
(emms-set-repeat-curr-mark)
(message "Repeat current track."))
(defun emms-player-any-unrepeat-curr ()
(setq emms-repeat-curr-track nil)
(emms-set-unrepeat-curr-mark)
(message "Stop repeating current track."))
(defun emms-player-any-repeat-all ()
(setq emms-repeat-curr-track nil
emms-repeat-playlist t)
(emms-set-repeat-all-mark)
(message "Repeat all tracks."))
(defun emms-player-any-unrepeat-all ()
(setq emms-repeat-curr-track nil
emms-repeat-playlist nil)
(emms-set-unrepeat-all-mark)
(message "Stop Repeating all tracks."))
(defun emms-repeat-curr ()
"Repeat current track."
(interactive)
(when emms-player-playing-p
(funcall (emms-player-get emms-player-playing-p 'repeat-curr))))
(defun emms-unrepeat-curr ()
"Stop repeating current track."
(interactive)
(when emms-player-playing-p
(funcall (emms-player-get emms-player-playing-p 'unrepeat-curr))))
(defun emms-repeat-all ()
"Repeat all tracks."
(interactive)
(when emms-player-playing-p
(funcall (emms-player-get emms-player-playing-p 'repeat-all))))
(defun emms-unrepeat-all ()
"Stop repeating all tracks."
(interactive)
(when emms-player-playing-p
(funcall (emms-player-get emms-player-playing-p 'unrepeat-all))))
(defun emms-set-repeat-curr-mark ()
"Add a star at front indicating repeats."
(setq emms-mode-line-format " [ * %s ] "
emms-mode-line-string
(funcall emms-mode-line-mode-line-function)))
(defun emms-set-unrepeat-curr-mark ()
"Remove star mark at front."
(setq emms-mode-line-format " [ %s ] "
emms-mode-line-string
(funcall emms-mode-line-mode-line-function)))
(defun emms-set-repeat-all-mark ()
"Add a star at front indicating repeats."
(setq emms-mode-line-format " [ ** %s ] "
emms-mode-line-string
(funcall emms-mode-line-mode-line-function)))
(defun emms-set-unrepeat-all-mark ()
"Remove star mark at front."
(setq emms-mode-line-format " [ %s ] "
emms-mode-line-string
(funcall emms-mode-line-mode-line-function)))
;; recommend key bindings
;; (global-set-key (kbd "C-c e SPC") 'emms-pause)
;; (global-set-key (kbd "C-c e r") 'emms-repeat-curr)
;; (global-set-key (kbd "C-c e R") 'emms-unrepeat-curr)
;; (global-set-key (kbd "C-c e <left>") (lambda () (interactive) (emms-seek
"-10")))
;; (global-set-key (kbd "C-c e <right>") (lambda () (interactive) (emms-seek
"+10")))
;; (global-set-key (kbd "C-c e <up>") (lambda () (interactive) (emms-seek
"-60")))
;; (global-set-key (kbd "C-c e <down>") (lambda () (interactive) (emms-seek
"+60")))
(provide 'emms+)
;; emms+.el ends here
;;; emms-lyric.el --- Display lyrics synchronically
;; Copyright (C) 2005 William XWL
;; Author: William XWL <address@hidden>
;; Maintainer: William XWL <address@hidden>
;; Created: 2005/07/17 15:08:18
;; Version: v 0.1
;; Keywords: emms music lyric
;; Last updated: 2005/07/17 20:34:51
;; This file is not part of GNU Emacs.
;;{{{ GPL
;; 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 2, 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, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;;}}}
;;; Commentary:
;; This package enables you to play music files and display lyrics
;; synchronically! :-) Note, you have to install emms package and
;; emms+.el(written by me as well) first.
;; Put this file into your load-path and the following into your
;; ~/.emacs:
;; (require 'emms-lyric)
;; Take a look at the "User Customizable" part for possible personal
;; customizations.
;;; Change Log:
;; v 0.1 [2005/07/17 20:07:30] Initial version.
;;; Known bugs:
;; 1. `emms-lyric-pause': Behave right when running for the first
;; time. Which means, you can only pause-continue once. :(
;; 2. Sometimes music playing would be blocked by some process, like
;; startup Gnus, while emms-lyric still goes on, thus make music and
;; lyrics asynchronical.
;;; Todo:
;; 1. Fix `emms-lyric-pause' bug.
;; 2. Add `emms-lyric-seek' support.
;;; Code:
(require 'emms)
(require 'emms+)
;;; User Customizable
(defvar emms-lyric-display-lyric-p t
"Whether to diplay lyrics or not.")
(defvar emms-lyric-display-lyric-on-mode-line t
"Display lyrics on mode line.")
(defvar emms-lyric-display-lyric-on-minibuffer nil
"Display lyrics on minibuffer.")
;;; Variables:
(defvar emms-lyric-alist nil
"a list of the form: '((time0 lyric0) (time1 lyric1)...)). In short,
at time-i, display lyric-i.")
(defvar emms-lyric-timers nil
"timers for displaying lyric.")
(defvar emms-lyric-start-time nil
"emms lyric start time.")
(defvar emms-lyric-pause-time nil
"emms lyric pause time.")
(defvar emms-lyric-mode-line-string ""
"current lyric.")
;;; Functions:
(defun emms-lyric-setup (file)
"Read FILE's lyric file (LRC format) if possible. The lyric file
should end up with \".lrc\", its format looks like:
[00:39.67]I love you, Emacs!
e.g,
foo.mp3
foo.lrc
FILE is foo.mp3 here. "
(let ((lrc-file
(replace-regexp-in-string "\\.mp3" ".lrc" file)))
(if (file-exists-p lrc-file)
(with-temp-buffer
(insert-file-contents lrc-file)
(while (search-forward-regexp
"\\[[0-9][0-9]:[0-9][0-9]\\.[0-9][0-9]\\].*" nil t)
(let ((lyric-string (match-string 0))
(time 0)
(lyric ""))
(setq lyric
(replace-regexp-in-string ".*\\]" "" lyric-string))
(while (string-match "\\[.*" lyric-string)
(setq time (+ (* (string-to-number (substring lyric-string 1 3))
60)
(string-to-number (substring lyric-string 4 9))
time)
lyric-string (substring lyric-string 10)
emms-lyric-alist (append emms-lyric-alist `((,time
,lyric))))
(setq time 0)))))
(setq emms-lyric-alist nil)
;; (message "Lyric file not found.")
)))
(defun emms-lyric-start ()
"Start displaying lryics on the mode line at right time. User should
not call this interactively. But together with `emms-start'."
(when emms-lyric-display-lyric-p
(emms-lyric-setup (cdaddr (emms-playlist-current-track)))
(setq emms-lyric-timers
(mapcar '(lambda (arg)
(let ((time (car arg))
(lyric (cadr arg)))
(run-at-time
(concat (number-to-string time) " sec")
nil 'emms-lyric-display lyric)))
emms-lyric-alist))
(setq emms-lyric-start-time (current-time))))
(add-hook 'emms-player-started-hook 'emms-lyric-start)
(defun emms-lyric-pause ()
"Toggle displaying lyrics. User should not call this
interactively. But together with `emms-pause'."
(when emms-lyric-display-lyric-p
(if emms-player-paused-p
(progn
(emms-lyric-stop)
(setq emms-lyric-pause-time (current-time)))
(let ((elapsed-time
(if emms-lyric-pause-time
(time-to-seconds
(time-subtract emms-lyric-pause-time
emms-lyric-start-time))
0)))
(setq emms-lyric-start-time (current-time))
(setq emms-lyric-timers
(mapcar
'(lambda (arg)
(let ((time (- (car arg) elapsed-time))
(lyric (cadr arg)))
(when (>= time 0)
(run-at-time
(concat (number-to-string time) " sec")
nil 'emms-lyric-display lyric))))
emms-lyric-alist))))))
(add-hook 'emms-player-paused-hook 'emms-lyric-pause)
(defun emms-lyric-stop ()
"Stop displaying lyrics."
(interactive)
(cancel-function-timers 'emms-lyric-display)
(setq emms-lyric-mode-line-string ""))
(add-hook 'emms-player-stopped-hook 'emms-lyric-stop)
(add-hook 'emms-player-finished-hook 'emms-lyric-stop)
(defun emms-lyric-mode-line ()
"Add lyric to the mode line."
(when (and emms-lyric-display-lyric-p
(not (member 'emms-lyric-mode-line-string
global-mode-string)))
(setq global-mode-string
(append global-mode-string '(emms-lyric-mode-line-string)))))
(defun emms-lyric-display (lyric)
"Display lyric.
LYRIC is current playing lyric.
See `emms-lyric-display-lyric-on-mode-line' and
`emms-lyric-display-lyric-on-minibuffer' on how to config where to
display."
(when emms-lyric-display-lyric-p
(when emms-lyric-display-lyric-on-mode-line
(emms-lyric-mode-line)
(setq emms-lyric-mode-line-string lyric)
(force-mode-line-update))
(when emms-lyric-display-lyric-on-minibuffer
(message lyric))))
(provide 'emms-lyric)
;;; emms-lyric.el ends here
- [emms-help] emms-lyric.el v0.1, emms+.el v0.2,
William XWL <=
- Re: [emms-help] emms-lyric.el v0.1, emms+.el v0.2, Jorgen Schaefer, 2005/07/17
- Re: [emms-help] emms-lyric.el v0.1, emms+.el v0.2, William Xu, 2005/07/17
- Re: [emms-help] emms-lyric.el v0.1, emms+.el v0.2, Jorgen Schaefer, 2005/07/17
- Re: [emms-help] emms-lyric.el v0.1, emms+.el v0.2, xwl, 2005/07/18
- Re: [emms-help] emms-lyric.el v0.1, emms+.el v0.2, Jorgen Schaefer, 2005/07/18
- Re: [emms-help] emms-lyric.el v0.1, emms+.el v0.2, xwl, 2005/07/18
- [emms-help] Re: emms-lyric.el v0.1, emms+.el v0.2, Lucas Bonnet, 2005/07/19
- Re: [emms-help] Re: emms-lyric.el v0.1, emms+.el v0.2, Yoni Rabkin, 2005/07/19
- [emms-help] Re: emms-lyric.el v0.1, emms+.el v0.2, Lucas Bonnet, 2005/07/19
- Re: [emms-help] Re: emms-lyric.el v0.1, emms+.el v0.2, Yoni Rabkin, 2005/07/19