[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/emms a84ebc7984: Add an EMMS module for fetching synchr
From: |
ELPA Syncer |
Subject: |
[elpa] externals/emms a84ebc7984: Add an EMMS module for fetching synchronized lyrics from LRCLIB |
Date: |
Wed, 27 Nov 2024 21:58:04 -0500 (EST) |
branch: externals/emms
commit a84ebc7984725a64177a70656a7860b1bf3f4d93
Author: Daniel Semyonov <daniel@dsemy.com>
Commit: Daniel Semyonov <daniel@dsemy.com>
Add an EMMS module for fetching synchronized lyrics from LRCLIB
---
doc/emms.texinfo | 22 ++++++++++
emms-lyrics-lrclib.el | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 136 insertions(+)
diff --git a/doc/emms.texinfo b/doc/emms.texinfo
index 43d474dd9e..e7d1300ec4 100644
--- a/doc/emms.texinfo
+++ b/doc/emms.texinfo
@@ -2735,6 +2735,24 @@ To add this feature we invoke:
(emms-lyrics 1)
@end lisp
+Synchronized lyrics files can be obtained manually from various
+sources, or fetched automatically for new tracks from an LRCLIB server
+(@url{https://lrclib.net}) by adding the following function to
+@var{emms-track-initialize-functions}:
+
+@defun emms-lyrics-lrclib-get &optional track force interactive
+Search for synchronized lyrics for @var{track} through LRCLIB’s API.
+If @var{track} is omitted or nil, use the selected track in the
+current playlist.
+When used as a track initialization function, @var{track} is set to
+the track being initialized.
+The lyrics are saved in an ``.lrc'' file alongside the track, unless
+the file already exists (in which case the search isn’t performed).
+When called interactively (non-nil INTERACTIVE), display informative
+messages, and with prefix argument FORCE, ask to overwrite existing
+``.lrc'' files.
+@end defun
+
There are a number of variables we can set to define the way that
`emms-lyrics' behaves, we can set these directly or by using the
Customize feature in Emacs.
@@ -2770,6 +2788,10 @@ Non-nil value will enable lyrics scrolling.
Interval between scroller timers. The shorter, the faster.
@end defvr
+@defvr {User Option} emms-lyrics-lrclib-url
+Base URL for LRCLIB API requests.
+@end defvr
+
We can control `emms-lyrics' with the help of the following functions:
@defun emms-lyrics-start
diff --git a/emms-lyrics-lrclib.el b/emms-lyrics-lrclib.el
new file mode 100644
index 0000000000..d862913de7
--- /dev/null
+++ b/emms-lyrics-lrclib.el
@@ -0,0 +1,114 @@
+;;; emms-lyrics-lrclib.el --- Fetch synchronized lyrics through LRCLIB -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2024 Free Software Foundation, Inc.
+
+;; Author: Daniel Semyonov <daniel@dsemy.com>
+
+;; 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 3, 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; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides a command/track initialization function which
+;; automatically fetches synchronized lyrics for tracks (the current
+;; track interactively) through an LRCLIB server.
+
+;;; Code:
+
+(require 'emms-lyrics)
+(require 'emms-later-do)
+
+(defgroup emms-lyrics-lrclib nil
+ "EMMS module for fetching synchronized lyrics through LRCLIB servers."
+ :group 'emms-lyrics
+ :prefix "emms-lyrics-lrclib-")
+
+(defcustom emms-lyrics-lrclib-url "https://lrclib.net/api/"
+ "Base URL for LRCLIB API requests."
+ :type 'string)
+
+(defconst emms-lyrics-lrclib-max-requests 250
+ "Maximum number of concurrent requests to LRCLIB.")
+
+(defvar emms-lyrics-lrclib-requests 0
+ "Current number of concurrent requests to LRCLIB.")
+
+(defun emms-lyrics-lrclib-encode-name (name)
+ "Encode (artist/album/track) NAME for an LRCLIB search."
+ (and (stringp name) (string-replace " " "+" name)))
+
+(defun emms-lyrics-lrclib-parse (_ file track interactive)
+ "Parse and save synced lyrics in FILE.
+If TRACK is the selected track in the current playlist, catch up.
+When INTERACTIVE is non-nil, display messages and confirm overwrite."
+ (unwind-protect
+ (progn
+ (search-forward "\n\n")
+ (let* ((p (json-parse-buffer))
+ (lyrics (and (hash-table-p p) (gethash "syncedLyrics" p))))
+ (if (not (stringp lyrics))
+ (when interactive (message "No lyrics found"))
+ (or
+ (and (file-exists-p file) interactive
+ (not (y-or-n-p
+ (format "Overwrite existing file (\"%s\")?" file))))
+ (with-temp-file file
+ (insert (gethash "syncedLyrics" p))
+ (when interactive
+ (message "Saves synced lyrics at \"%s\"" file))
+ (and (boundp 'emms-lyrics-display-p)
+ emms-lyrics-display-p emms-player-playing-p
+ (equal track (emms-playlist-current-selected-track))
+ (emms-lyrics-catchup file)))))))
+ (setq emms-lyrics-lrclib-requests (1- emms-lyrics-lrclib-requests))))
+
+;;;###autoload
+(defun emms-lyrics-lrclib-get (&optional track force interactive)
+ "Search for synchronized lyrics for TRACK through LRCLIB's API.
+If TRACK is omitted or nil, use the selected track in the current playlist.
+The lyrics are saved in an \".lrc\" file alongside the track, unless the
+file already exists (in which case the search isn't performed).
+When called interactively (non-nil INTERACTIVE), display informative
+messages, and with prefix argument FORCE, ask to overwrite existing
+\".lrc\" files."
+ (interactive (list nil current-prefix-arg t))
+ (if (> emms-lyrics-lrclib-requests emms-lyrics-lrclib-max-requests)
+ (emms-later-do #'emms-lyrics-lrclib-get track force interactive)
+ (when-let* ((track (or track (emms-playlist-current-selected-track)))
+ ((eq (emms-track-type track) 'file))
+ (file (emms-track-name track))
+ (lrc (replace-regexp-in-string "\\.[^.]+\\'" ".lrc" file))
+ ((or force (not (file-exists-p lrc))))
+ ((file-writable-p lrc))
+ (title (emms-lyrics-lrclib-encode-name
+ (emms-track-get track 'info-title)))
+ (artist (emms-lyrics-lrclib-encode-name
+ (emms-track-get track 'info-artist)))
+ (album (emms-lyrics-lrclib-encode-name
+ (emms-track-get track 'info-album)))
+ (time (emms-track-get track 'info-playing-time)))
+ (setq emms-lyrics-lrclib-requests (1+ emms-lyrics-lrclib-requests))
+ (when interactive (message "Searching for lyrics..."))
+ (url-retrieve
+ (url-encode-url
+ (format "%sget?artist_name=%s&track_name=%s&album_name=%s&duration=%d"
+ emms-lyrics-lrclib-url artist title album time))
+ #'emms-lyrics-lrclib-parse (list lrc track interactive)))))
+
+(provide 'emms-lyrics-lrclib)
+
+;;; emms-lyrics-lrclib.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/emms a84ebc7984: Add an EMMS module for fetching synchronized lyrics from LRCLIB,
ELPA Syncer <=