| 1 | ;;; emms-player-xine.el --- xine support for EMMS -*- lexical-binding: t; -*- |
| 2 | |
| 3 | ;; Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Author: Tassilo Horn <tassilo@member.fsf.org> |
| 6 | |
| 7 | ;; This file is part of EMMS. |
| 8 | |
| 9 | ;; EMMS is free software; you can redistribute it and/or |
| 10 | ;; modify it under the terms of the GNU General Public License |
| 11 | ;; as published by the Free Software Foundation; either version 3 |
| 12 | ;; of the License, or (at your option) any later version. |
| 13 | |
| 14 | ;; EMMS is distributed in the hope that it will be useful, |
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 | ;; GNU General Public License for more details. |
| 18 | |
| 19 | ;; You should have received a copy of the GNU General Public License |
| 20 | ;; along with EMMS; if not, write to the Free Software Foundation, |
| 21 | ;; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
| 22 | |
| 23 | ;;; Commentary: |
| 24 | |
| 25 | ;; This provides a player that uses xine. It supports pause and |
| 26 | ;; seeking. |
| 27 | |
| 28 | ;;; Code: |
| 29 | |
| 30 | ;; TODO: The video window cannot be disabled. I asked on |
| 31 | ;; gmane.comp.video.xine.user (<87y7ohqcbq.fsf@baldur.tsdh.de>)... |
| 32 | |
| 33 | ;; TODO: Implement seek-to with "SetPositionX%\n" where X is in {0,10,..,90} |
| 34 | |
| 35 | (require 'emms-player-simple) |
| 36 | |
| 37 | (define-emms-simple-player xine '(file url) |
| 38 | (concat "\\`\\(http[s]?\\|mms\\)://\\|" |
| 39 | (emms-player-simple-regexp |
| 40 | "ogg" "mp3" "wav" "mpg" "mpeg" "wmv" "wma" |
| 41 | "mov" "avi" "divx" "ogm" "ogv" "asf" "mkv" |
| 42 | "rm" "rmvb" "mp4" "flac" "vob")) |
| 43 | "xine" "--no-gui" "--no-logo" "--no-splash" "--no-reload" "--stdctl") |
| 44 | |
| 45 | (emms-player-set emms-player-xine |
| 46 | 'pause |
| 47 | 'emms-player-xine-pause) |
| 48 | |
| 49 | ;;; Pause is also resume for xine |
| 50 | (emms-player-set emms-player-xine |
| 51 | 'resume |
| 52 | nil) |
| 53 | |
| 54 | (emms-player-set emms-player-xine |
| 55 | 'seek |
| 56 | 'emms-player-xine-seek) |
| 57 | |
| 58 | (defun emms-player-xine-pause () |
| 59 | "Depends on xine's --stdctl mode." |
| 60 | (process-send-string |
| 61 | emms-player-simple-process-name "pause\n")) |
| 62 | |
| 63 | (defun emms-player-xine-seek (secs) |
| 64 | "Depends on xine's --stdctl mode." |
| 65 | ;; xine-ui's stdctl supports only seeking forward/backward in 7/15/30 and 60 |
| 66 | ;; second steps, so we take the value that is nearest to SECS. |
| 67 | (let ((s (emms-nearest-value secs '(-60 -30 -15 -7 7 15 30 60)))) |
| 68 | (when (/= s secs) |
| 69 | (message (concat "EMMS: Xine only supports seeking for [+/-] 7/15/30/60 " |
| 70 | "seconds, so we seeked %d seconds") s)) |
| 71 | (process-send-string |
| 72 | emms-player-simple-process-name |
| 73 | (if (< s 0) |
| 74 | (format "SeekRelative%d\n" s) |
| 75 | (format "SeekRelative+%d\n" s))))) |
| 76 | |
| 77 | (defun emms-nearest-value (val list) |
| 78 | "Returns the value of LIST which is nearest to VAL. |
| 79 | |
| 80 | LIST should be a list of integers." |
| 81 | (let* ((nearest (car list)) |
| 82 | (dist (abs (- val nearest)))) |
| 83 | (dolist (lval (cdr list)) |
| 84 | (let ((ndist (abs (- val lval)))) |
| 85 | (when (< ndist dist) |
| 86 | (setq nearest lval |
| 87 | dist ndist)))) |
| 88 | nearest)) |
| 89 | |
| 90 | |
| 91 | (provide 'emms-player-xine) |
| 92 | ;;; emms-player-xine.el ends here |