;; Contact <francois@fleuret.org> for comments & bug reports ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Is it me, or the slave mode of mplayer is ugly to parse ? Did I
-;; miss something ?
+;; Is it me, or the slave mode of mplayer is ugly to parse? Did I miss
+;; something?
+
+(defcustom media/mplayer/executable "mplayer"
+ "The name of the executable."
+ :type 'string
+ :group 'media)
(defcustom media/mplayer/args nil
"List of arguments for mplayer."
:type 'float
:group 'media)
+(defcustom media/mplayer/capture-dir nil
+ "States where to save the dumped streams."
+ :type 'string
+ :group 'media)
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; It is impossible to tell mplayer to send information every time dt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(setq media/mplayer/protocol-regexp
+ "^\\(AUDIO:\\|Exiting...\\|Starting\\|ANS_LENGTH\\|ANS_TIME_POSITION\\|Cache fill:\\|ICY Info:\\) *\\(.*\\)$")
+
(defun media/mplayer/filter-subfunctions (cmd param)
- ;; (unless (string= cmd "A:")
- ;; (message "cmd=%s param=%s" cmd param)
- ;; )
+ ;; (unless (string= cmd "A:")
+ ;; (message "cmd=%s param=%s" cmd param)
+ ;; )
(eval
- (cdr
- (assoc cmd
+ (cons 'progn
+ (cdr
+ (assoc cmd
+
+ '(
+ ("ICY Info:"
+ ;; (message "ICY Info \"%s\"" param)
+
+ (if (string-match "StreamTitle='\\([^;]*\\)';" param)
+
+ (setq media/current-song-in-stream
+ (let ((s (match-string 1 param)))
+ (concat (if (string= s "")
+ "<no title>"
+ (encode-coding-string s 'latin-1)
+ ;; s
+ )
+ " | "
+ (format-time-string "%a %b %d %H:%M:%S")
+ )
+ )
+ )
+
+ ;; If we did not parse it properly, reset the
+ ;; song name, and display the ICY string raw
+ (setq media/current-song-in-stream nil)
+ (message "ICY Info \"%s\"" param)
+ )
+
+ (when media/mplayer/capture-dir
+ (let ((coding-system-for-write 'raw-text-unix))
+ (with-temp-buffer
+ (insert
+ (concat media/current-song-in-stream "\n"))
+ (write-region nil nil (concat media/mplayer/capture-dir "/log") t))))
+
+ (if (and media/current-song-in-stream media/current-information)
+ (media/show-current-information))
+ )
- '(
+ ;; ----------------------------------------
- ;; ----------------------------------------
+ ("ANS_LENGTH"
- ("ANS_LENGTH" .
+ (setq media/song-duration
+ (string-to-number (substring param 1))))
- (setq media/song-duration
- (string-to-number (substring param 1))))
+ ;; ----------------------------------------
- ;; ----------------------------------------
+ ("ANS_TIME_POSITION"
- ("ANS_TIME_POSITION" .
+ (setq media/song-current-time
+ (string-to-number (substring param 1)))
- (progn
- (setq media/song-current-time
- (string-to-number (substring param 1)))
+ (when (and media/duration-to-history
+ (< media/mplayer/cumulated-duration media/duration-to-history))
- (when (and media/duration-to-history
- (< media/mplayer/cumulated-duration media/duration-to-history))
+ (when media/mplayer/last-current-time
+ (setq media/mplayer/cumulated-duration
+ (+ media/mplayer/cumulated-duration
+ (- media/song-current-time media/mplayer/last-current-time))))
- (when media/mplayer/last-current-time
- (setq media/mplayer/cumulated-duration
- (+ media/mplayer/cumulated-duration
- (- media/song-current-time media/mplayer/last-current-time))))
+ (when (>= media/mplayer/cumulated-duration media/duration-to-history)
+ (media/put-in-history)
+ )
- (when (>= media/mplayer/cumulated-duration media/duration-to-history)
- (media/put-in-history)
+ (setq media/mplayer/last-current-time media/song-current-time)
+ )
)
- (setq media/mplayer/last-current-time media/song-current-time)
- )
-
-
- )
- )
-
- ;; ----------------------------------------
+ ;; ----------------------------------------
- ("AUDIO:" .
+ ("AUDIO:"
- (progn
- ;; param = "44100 Hz, 2 ch, s16le, 128.0 kbit/9.07% (ratio: 16000->176400)"
- (when (string-match "^\\([0-9]+\\) Hz, \\([0-9]+\\) ch.* \\([0-9.]+\\) kbit"
- param)
- (setq media/current-information
- (list media/mplayer/url
- (string-to-number (match-string 1 param))
- (string-to-number (match-string 2 param))
- (string-to-number (match-string 3 param))))
- )
- (run-hooks 'media/play-hook)
- ))
-
- ;; ----------------------------------------
-
- ("Starting" .
- (media/mplayer/write "get_time_length\n"))
+ ;; param = "44100 Hz, 2 ch, s16le, 128.0 kbit/9.07% (ratio: 16000->176400)"
+ (when (string-match "^\\([0-9]+\\) Hz, \\([0-9]+\\) ch.* \\([0-9.]+\\) kbit"
+ param)
+ (setq media/current-information
+ (list media/mplayer/url
+ (string-to-number (match-string 1 param))
+ (string-to-number (match-string 2 param))
+ (string-to-number (match-string 3 param))))
+ )
+ (run-hooks 'media/play-hook)
+ )
- ;; ----------------------------------------
+ ;; ----------------------------------------
- ("Cache fill:" .
+ ("Starting"
+ (media/mplayer/write "get_time_length\n")
+ (when media/mplayer/capture-dir
+ (media/mplayer/write "capturing\n")
+ ;; (message "Capturing stream in %s" media/mplayer/capture-dir)
+ )
+ )
- (when (string-match "(\\([0-9]+\\) bytes" param)
- (message "Caching stream (%dkb)"
- (/ (string-to-number (match-string 1 param)) 1024))))
+ ;; ----------------------------------------
- ;; ----------------------------------------
+ ("Cache fill:"
+ (when (string-match "(\\([0-9]+\\) bytes" param)
+ (message "Caching stream (%dkb)"
+ (/ (string-to-number (match-string 1 param)) 1024))))
- ("Exiting..." .
+ ;; ----------------------------------------
- (progn
- (setq media/mplayer/exit-type
- (cdr (assoc param '(("(End of file)" . file-finished)
- ("(Quit)" . quit))))
- media/current-information nil
- media/song-duration nil
- media/song-current-time nil)
+ ("Exiting..."
+ (setq media/mplayer/exit-type
+ (cdr (assoc param '(("(End of file)" . file-finished)
+ ("(Quit)" . quit))))
+ media/current-information nil
+ media/song-duration nil
+ media/song-current-time nil)
- (when media/mplayer/process (kill-process media/mplayer/process))
+ (when media/mplayer/process (kill-process media/mplayer/process))
- (force-mode-line-update)))
+ (force-mode-line-update)
+ )
- ;; ----------------------------------------
+ ;; ----------------------------------------
- )
- ))))
+ )
+ )
+ )
+ )
+ )
+ )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(string-match "\\(.*\\)[\n\r]+" media/mplayer/buffer start))
(setq start (1+ (match-end 1)))
(let ((line (match-string 1 media/mplayer/buffer)))
- (when (string-match "^\\(AUDIO:\\|Exiting...\\|Starting\\|ANS_LENGTH\\|ANS_TIME_POSITION\\|Cache fill:\\) *\\(.*\\)$" line)
- (media/mplayer/filter-subfunctions (match-string 1 line) (match-string 2 line)))))
+ (when (string-match media/mplayer/protocol-regexp line)
+ (media/mplayer/filter-subfunctions (match-string 1 line) (match-string 2 line))))
+ )
(setq media/mplayer/buffer (substring media/mplayer/buffer start)))
)
media/song-current-time nil
media/mplayer/cumulated-duration 0
media/mplayer/last-current-time nil
- ))
+ )
+)
(defun media/api/cleanup () "Called when killing the application's buffer"
(when media/mplayer/process
(apply
'start-process
(append
- '("mplayer" nil "mplayer" "-slave" "-quiet")
+ `("mplayer" nil ,media/mplayer/executable "-slave" "-quiet")
media/mplayer/args
- (if (string-match "\\(asx\\|m3u\\|pls\\|ram\\)$" media/mplayer/url)
+ (when (string-match "\\(asx\\|m3u\\|pls\\|ram\\)$" media/mplayer/url)
+ (if media/mplayer/capture-dir
+ (list "-dumpfile"
+ (concat media/mplayer/capture-dir
+ "/"
+ (replace-regexp-in-string "[^a-zA-Z0-9\.]" "_" media/mplayer/url)
+ (format-time-string "-%Y-%m-%d-%H:%M:%S"))
+ "-capture"
+ "-playlist"
+ )
(list "-playlist"))
- (list (replace-regexp-in-string "^file://" "" media/mplayer/url))))
+ )
+ (list (replace-regexp-in-string "^file://" "" media/mplayer/url)))
+ )
media/mplayer/exit-type 'unknown
media/mplayer/paused nil
media/song-duration nil
(process-kill-without-query media/mplayer/process)
(media/mplayer/start-timing-requests)
(media/mplayer/write "get_time_pos\n")
-
)
(defun media/api/stop () (interactive)