From: Michael Brand <michael.ch.brand@gmail.com>
To: Org Mode <emacs-orgmode@gnu.org>
Subject: org-player and switch to lexical binding in org.el
Date: Sun, 17 Jan 2016 19:58:38 +0100 [thread overview]
Message-ID: <CALn3zoh+ACSU09eRurfwKjmCnw7i-_0KX7tA2jWqtu=vvQepLQ@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 387 bytes --]
Hi all
release_8.3.3-426-g1f49e9f introduces a regression. The link
[[file:/dir/audio.mp3::0:12:34]]
results in
Debugger entered--Lisp error: (void-variable search)
(org-player-play-file file search)
[...]
org-open-file("/dir/audio.mp3" nil nil "0:12:34")
[...]
I hope it is reproducible after (require 'org-player), org-player.el
attached.
Michael
[-- Attachment #2: org-player.el --]
[-- Type: application/octet-stream, Size: 10372 bytes --]
;;; -*- coding: utf-8-unix -*-
;;; org-player.el - Play audio and video files in org-mode hyperlinks
;;;
;;; Author: Paul Sexton <eeeickythump@gmail.com>
;;; Version: 1.0.0
;;; Repository at http://bitbucket.org/eeeickythump/org-player/
;;;
;;;
;;; Synopsis
;;; ========
;;;
;;; I was learning a language, and wanted to include hyperlinks to audio files
;;; within my org document, and to be able to play each file by clicking on its
;;; link. I wrote the code in this file, which makes org mode use an Emacs
;;; media player library, Bongo, to play audio and video files contained in
;;; 'file:' hyperlinks.
;;;
;;; Installation
;;; ============
;;;
;;; First you will need to install Bongo, which you can download from:
;;; https://github.com/dbrock/bongo
;;;
;;; You will also need to ensure you have an actual media player program
;;; installed, and you need to tell Bongo which program to use to play files. I
;;; have tested org-player with MPlayer, an open source media player which
;;; works well on Windows and Linux. VLC does not work with Bongo on Windows at
;;; the time of writing.
;;;
;;; You can obtain MPlayer from:
;;; http://www.mplayerhq.hu/design7/news.html
;;;
;;; Ensure you have Bongo set up and working. Once this is achieved, installing
;;; org-player is easy - just put the file somewhere in your Emacs load-path
;;; and put (require 'org-player) in your .emacs file.
;;;
;;; Usage
;;; =====
;;;
;;; Clicking on a link such as
;;;
;;; [[file:/path/to/song.mp3]]
;;;
;;; adds it to the active Bongo playlist and immediately starts playing
;;; it. Playback can be paused, fast-forwarded etc using Bongo commands (see
;;; below).
;;;
;;; Links can also specify track positions. When a link contains a track
;;; position, playback will start at that position in the track. For example:
;;;
;;; [[file:/path/to/song.mp3::2:43]] Starts playback at 2 min 43 sec.
;;; [[file:/path/to/song.mp3::1:10:45]] Starts playback at 1 hr 10 min 45 sec.
;;; [[file:/path/to/song.mp3::3m15s]] Starts playback at 3 min 15 sec.
;;; [[file:/path/to/song.mp3::49s]] Starts playback at 0 min 49 sec.
;;; [[file:/path/to/song.mp3::1h21m10s]] Starts playback at 1 hr 21 min 10 sec.
;;;
;;; Controlling playback
;;; ====================
;;;
;;; When Bongo plays a file it puts some icons in the modeline that resemble the
;;; well-known symbols for 'play', 'stop', 'rewind' and so on, and which can be
;;; used to control playback using the mouse. I found these worked erratically when
;;; outside the actual Bongo playlist buffer, so I have instead bound some org-mode
;;; keys (ctrl + numpad keys) to the relevant functions. These are:
;;;
;;; C-<keypad 0> pause/resume
;;; C-<keypad .> stop, or restart playback from beginning
;;; C-<keypad /> show track info
;;; C-<keypad 4> skip back 10 seconds
;;; C-<keypad 6> skip forward 10 seconds
;;; C-<keypad 9> increase volume (requires separate 'volume' library
;;; at https://github.com/dbrock/volume-el )
;;; C-<keypad 3> decrease volume
;;;
;;; Note that these keys (and the modeline icons, if they work) act on the
;;; track that is active in the Bongo playlist. This will always be the last
;;; track that you added by clicking on a link in org-mode, unless you alter
;;; the Bongo playlist outside org mode.
;;;
;;; Also note that these keys are only bound within org mode buffers.
;;;
;;; Notes
;;; =====
;;;
;;; I have only tested this with MP3 files, but it ought to work with
;;; video as well, as both MPlayer and Bongo claim to work with video files.
;;;
;;; Future plans
;;; ============
;;;
;;; If anyone wants to integrate this code with EMMS, another popular Emacs
;;; media player library, contributions would be welcome.
(require 'org)
(require 'bongo)
(defvar org-player-file-extensions-regexp
(concat "\\." (regexp-opt
(append bongo-audio-file-name-extensions
bongo-video-file-name-extensions))))
(add-to-list 'org-file-apps
(cons (concat org-player-file-extensions-regexp "$")
'(org-player-play-file file)))
(add-to-list 'org-file-apps
(cons (concat org-player-file-extensions-regexp
"::[0-9]+:[0-9]+\\(:[0-9]+\\|\\)")
'(org-player-play-file file search)))
(add-to-list 'org-file-apps
(cons (concat org-player-file-extensions-regexp
"::[0-9]+[HhMmSs]\\([0-9]+[MmSs]\\|\\)\\([0-9]+[MmSs]\\|\\)")
'(org-player-play-file file search)))
(defun org-player-string-to-time (str)
"Understands any of the following formats: MM:SS, HH:MM:SS, NNhNNmNNs,
NNhNNm, NNmNNs, NNh, NNm, NNs."
(let ((str (substring-no-properties str))
hours mins secs)
(cond
((string-match "\\([0-9]+\\):\\([0-9]+\\)\\(:[0-9.]+\\|\\)" str)
(if (string= "" (match-string 3 str)) ; XX:YY
(setq mins (match-string 1 str)
secs (match-string 2 str))
(setq hours (match-string 1 str) ; XX:YY:ZZ
mins (match-string 2 str)
secs (subseq (match-string 3 str) 1))))
((eq (string-match "[0-9]+[HhMmSs]" str)
(string-match "\\([0-9]+[Hh]\\|\\)\\([0-9]+[Mm]\\|\\)\\([0-9.]+[Ss]\\|\\)"
str))
(setq hours (match-string 1 str)
mins (match-string 2 str)
secs (match-string 3 str))
(unless (string= "" hours)
(setq hours (subseq hours 0 (1- (length hours)))))
(unless (string= "" mins)
(setq mins (subseq mins 0 (1- (length mins)))))
(unless (string= "" secs)
(setq secs (subseq secs 0 (1- (length secs))))))
(t
(error "Unrecognised track position specifier: %S" str)))
(setq hours (if (or (null hours) (string= "" hours))
0 (read hours)))
(setq mins (if (or (null mins) (string= "" mins))
0 (read mins)))
(setq secs (if (or (null secs) (string= "" secs))
0 (read secs)))
(list hours mins secs)))
(defun org-player-play-file (filename &optional pos)
"POS, if given, is a string that specifies a track position where
playback should begin. This string is taken from the portion of the
hyperlink that follows a double colon. For example:
[[file:song.mp3::03:22]]
[[file:song.mp3::1h24m3s]]
See `org-player-string-to-time' for a description of the format of
the POS string."
(let ((seek (if pos
(destructuring-bind (hours mins secs)
(org-player-string-to-time pos)
(+ secs
(* mins 60)
(* hours 60 60))))))
(with-bongo-buffer
(bongo-insert-file filename)
(backward-char)
(org-player-start/stop 'play seek)
(when seek
(bongo-seek-to seek)))))
(defun org-player-get-track-info ()
"Returns a list: (TRACKTITLE ALBUMNAME ARTISTNAME ELAPSEDSECS LENGTHSECS)"
(with-bongo-buffer
(let* ((info (bongo-line-infoset))
(track (cdr (assoc 'track info))))
(message "%s" info)
(list (cdr (assoc 'title track))
(cdr (assoc 'album info))
(cdr (assoc 'artist info))
(or (bongo-elapsed-time) 0)
(or (bongo-total-time) 0)))))
(defun org-player-print-track-info ()
"Print out some info about the active track, in the minibuffer."
(interactive)
(destructuring-bind (title album artist elapsed total)
(org-player-get-track-info)
(message "%s" (list title album artist elapsed total))
(cond
((null title)
(message "No active track."))
(t
(message "Track: %s
Album: %s / %s
%s / %s (%d%%) %s"
title album artist
(format "%02d:%02d" (floor elapsed 60) (mod elapsed 60))
(format "%02d:%02d" (floor total 60) (mod total 60))
(/ (* elapsed 100) total)
(cond
((bongo-paused-p) "(paused)")
((bongo-playing-p) "(playing)")
(t "(stopped)"))
)))))
(defun org-player-pause/resume ()
(interactive)
(destructuring-bind (title album artist elapsed total)
(org-player-get-track-info)
(when title
(message "%02d:%02d/%02d:%02d %s %s (%s / %s)"
(floor elapsed 60) (mod elapsed 60)
(floor total 60) (mod total 60)
(if (bongo-paused-p) "Unpaused:" "Paused:")
title album artist)))
(bongo-pause/resume))
(defun org-player-start/stop (&optional force starting-pos)
(interactive)
(destructuring-bind (title album artist elapsed total)
(org-player-get-track-info)
(when title
(cond
((eq force 'play)
(bongo-play))
((eq force 'stop)
(bongo-stop))
(t
(bongo-start/stop)))
(let ((msg (format "%02d:%02d/%02d:%02d %s %s (%s / %s)"
(floor (or starting-pos 0) 60)
(mod (or starting-pos 0) 60)
(floor total 60) (mod total 60)
(if (bongo-playing-p) "Playing:" "Stopped:")
title album artist)))
(message msg)))))
;; Numpad Ctrl-0: pause/resume
(define-key org-mode-map (kbd "<C-kp-0>") 'org-player-pause/resume)
(define-key org-mode-map (kbd "<C-kp-insert>") 'org-player-pause/resume)
;; Numpad Ctrl-.: stop current track, or restart from beginning if stopped
(define-key org-mode-map (kbd "<C-kp-decimal>") 'org-player-start/stop)
(define-key org-mode-map (kbd "<C-kp-delete>") 'org-player-start/stop)
;; Numpad Ctrl-PgUp, Ctrl-PgDn: raise/lower volume
(define-key org-mode-map (kbd "<C-kp-prior>") 'volume-raise)
(define-key org-mode-map (kbd "<C-kp-next>") 'volume-lower)
(define-key org-mode-map (kbd "<C-kp-9>") 'volume-raise)
(define-key org-mode-map (kbd "<C-kp-3>") 'volume-lower)
;; Numpad Ctrl-left, Ctrl-right: skip back/forward 10 seconds
(define-key org-mode-map (kbd "<C-kp-left>") 'bongo-seek-backward-10)
(define-key org-mode-map (kbd "<C-kp-right>") 'bongo-seek-forward-10)
(define-key org-mode-map (kbd "<C-kp-4>") 'bongo-seek-backward-10)
(define-key org-mode-map (kbd "<C-kp-6>") 'bongo-seek-forward-10)
;; Ctrl-/: show track info
(define-key org-mode-map (kbd "<C-kp-divide>") 'org-player-print-track-info)
(provide 'org-player)
next reply other threads:[~2016-01-17 18:58 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-17 18:58 Michael Brand [this message]
2016-01-17 20:40 ` org-player and switch to lexical binding in org.el Nicolas Goaziou
2016-01-17 21:02 ` Michael Brand
2016-01-17 21:05 ` Michael Brand
[not found] ` <CAK5Vzd2aV7WGGVr=+VF-LCCDCOZXJzUYEnCgbuzgGea4i5BR7Q@mail.gmail.com>
2016-02-07 11:49 ` Michael Brand
2016-01-28 11:37 ` Michael Brand
2016-01-29 13:32 ` Nicolas Goaziou
2016-01-29 20:39 ` Michael Brand
2016-01-30 23:30 ` Nicolas Goaziou
2016-02-01 7:57 ` Michael Brand
2016-02-03 17:33 ` Nicolas Goaziou
2016-02-03 20:41 ` Michael Brand
2016-02-03 20:56 ` Nicolas Goaziou
2016-02-03 22:02 ` Michael Brand
2016-02-04 8:36 ` Nicolas Goaziou
2016-02-04 11:44 ` Michael Brand
2016-02-04 12:46 ` Nicolas Goaziou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CALn3zoh+ACSU09eRurfwKjmCnw7i-_0KX7tA2jWqtu=vvQepLQ@mail.gmail.com' \
--to=michael.ch.brand@gmail.com \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).