用 Emacs + SMPlayer 看動畫/影片

###廢話###
我在做一些不太需要大腦的學校作業時有配動畫這種好習慣,但常常雙手都沾滿黏土顏料時,動畫一話看完還要按下一集很麻煩,所以我會 cd 到某部動畫的資料夾下後:

1
for i in *;do mplayer $i;done

用這種方法可以一口氣看完一整部動畫手都不用動,但不夠好用。不過現在我們有 Emacs 跟 Dired。

在 Emacs 上要看影片聽音樂有 EMMS 這個選擇,但個人覺得這個做得太複雜,當初設定我也弄不太起來,所以乾脆自己搞一個剛好夠用、設定又簡易的函數。

我平常是偏好使用 SMPlayer 作為影片播放器,功能完整自訂性高,而且他有提供把檔案直接加入 playlist 的參數-add-to-playlist,於是搭配Dired就很好實作了:

###程式碼###

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(defun dired-add-to-smplayer-playlist ()
"Add a multimedia file or all multimedia files under a directory into SMPlayer's playlist via Dired."
(interactive)
(require 'cl)
(let* (PATTERN FILE full-path-FILE n)
(setq PATTERN "\\(\\.mp4\\|\\.flv\\|\\.rmvb\\|\\.mkv\\|\\.avi\\|\\.rm\\|\\.mp3\\|\\.wav\\|\\.wma\\|\\.m4a\\|\\.mpeg\\|\\.aac\\|\\.ogg\\|\\.flac\\|\\.ape\\|\\.mp2\\|\\.wmv\\)$")
(setq FILE (dired-get-filename nil t))
(setq n 0)
(if (file-directory-p FILE) ;if it's a dir.
(progn
(setq full-path-FILE (directory-files FILE t PATTERN))
(message "Opening %s files..." (list-length full-path-FILE))
(cl-loop for i in full-path-FILE
do (call-process "smplayer" nil 0 nil "-add-to-playlist" i)
(sit-for 0.1)) ;Or playlist will be not in order.
(dired-next-line 1)
)
(if (string-match PATTERN FILE) ;if it's a file
(progn
(call-process "smplayer" nil 0 nil "-add-to-playlist" FILE)
(dired-next-line 1))
(progn
(message "This is not a supported audio or video file.")
(dired-next-line 1))))))
(define-key dired-mode-map (kbd "M-a") 'dired-add-to-smplayer-playlist)

###使用方法###

  • C-x C-f用 Dired 進入你存影片的目錄,移動到想要播放的檔案後按下M-a即可。
  • 可以一直按,會一路加下去。
  • 可以直接把整個目錄內的影音檔加進播放清單(目錄僅限一層以免發生意外:P),方法一樣是游標移動到想要加入的目錄後按下M-a

用用看就知道了,很方便的~ =w=+

只是這有個問題…就是呼叫外部程式我只在 Linux 下測過,MacOS 我沒測過不知道…或許可以用吧,Windows 的話則是根本不知該怎麼做也不打算知道(被拖走)。

##[2014-01-08 水] 更新
後來 Timothy Lin 提醒,SMPlayer 自己就會偵測輸入路徑是否為一個目錄,是目錄的話就會自己把目錄內的所有檔案加入 playlist,所以好像不用用到cl-loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun dired-add-to-smplayer-playlist ()
"Add a multimedia file or all multimedia files under a directory into SMPlayer's playlist via Dired."
(interactive)
(let (PATTERN FILE)
(setq PATTERN "\\(\\.mp4\\|\\.flv\\|\\.rmvb\\|\\.mkv\\|\\.avi\\|\\.rm\\|\\.mp3\\|\\.wav\\|\\.wma\\|\\.m4a\\|\\.mpeg\\|\\.aac\\|\\.ogg\\|\\.flac\\|\\.ape\\|\\.mp2\\|\\.wmv\\)$"
FILE (dired-get-filename nil t))
(if (file-directory-p FILE) ;if it's a dir.
(if (directory-files FILE nil PATTERN) ;if directory contains media file(s)
(call-process "smplayer" nil 0 nil "-add-to-playlist" FILE)
(message "This directory doesn't contain any media file."))
(if (string-match PATTERN FILE) ;if it's supported file
(call-process "smplayer" nil 0 nil "-add-to-playlist" FILE)
(message "This is not a supported audio or video file.")))
(dired-next-line 1)))
(define-key dired-mode-map (kbd "M-a") 'dired-add-to-smplayer-playlist)

然而發現一個好像是 smplayer 的問題,就是當 playlist 裡面已經有項目時,再加目錄的路徑進去會無效(會變成加入無法播放的奇怪項目),所以還是得一項項加進去…。