-
Notifications
You must be signed in to change notification settings - Fork 0
/
douban-music.el
159 lines (140 loc) · 3.87 KB
/
douban-music.el
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
;;;douban-music.el
;;;Author: Xiang Wang ([email protected])
;;
;;
;;code:
(eval-when-compile
(require 'cl))
(require 'url-http)
(require 'json)
(defgroup douban-music nil
"douban music interface"
:group 'entertainment
:prefix "douban-music-" )
(defvar local-music-store '()
"Song information in local store.
This store is a containner which pulls data from remote server, and
feed data to music player")
(defvar channel-number (random 20))
(defcustom douban-music-server (concat "http://douban.fm/j/mine/playlist?type=n&channel="
(number-to-string channel-number))
"douban server url address"
:group 'douban-music)
(defvar current-song '()
"The current Song that music player is opened"
)
(defun douban-music-fetch-songs-from-server ()
(interactive)
"Get next songs from douban server"
(let ((url douban-music-server)
(url-request-method "GET")
(url-request-data nil)
(url-request-extra-headers '(("Content-Length" . "0")))
(url-mime-charset-string)
(url-extensions-header)
(url-show-status)
json
buffer)
(setq buffer (url-retrieve-synchronously url))
(with-current-buffer buffer
(goto-char (point-max))
(setq json (cdr (assoc 'song
(json-read-from-string
(buffer-substring
(line-beginning-position)
(point-max))))))
( if (vectorp json)
(copy-to-local-store json)
(progn
(error "Invalid data format")
)
)
)
(kill-buffer buffer)
)
)
(defun copy-to-local-store (data)
( if (vectorp data)
(progn
(if (vectorp local-music-store)
(error "Should be list"))
(dotimes (i (length data))
( let ((var (aref data i)))
(setq local-music-store
(cons var local-music-store))
)
))
(error "Invalid data format")
)
)
(defun douban-music-pop-song-from-store ()
"Pop up a muisc from local music store"
(let ((song))
( if (eq nil local-music-store )
(progn
(douban-music-fetch-songs-from-server)
(setq channel-number (random 20))
)
)
(if (eq nil local-music-store)
(error "Fail to fetch muiscs from douban music server"))
(setq song (elt local-music-store 0))
(setq local-music-store (cdr local-music-store))
song
)
)
(defun play-music-filter ( proc string)
(if (string-match "finished" string)
(progn
(kill-douban-music-process)
(douban-music-play-song)
)
)
)
(defun douban-music-play-song ()
(interactive)
(let ((song )
(is-play nil))
(dolist (elt (process-list))
(if (string-match "douban-music-proc<?[0-9]*>?" (process-name elt))
(setq is-play t)
)
)
(if ( eq is-play nil)
(progn
(setq current-song (douban-music-pop-song-from-store))
(setq song current-song)
(set-process-filter
(start-process "douban-music-proc" nil "mpg123" (aget song 'url))
'play-music-filter
)
)
(message "Current Music is playing.")
)
)
)
(defun douban-music-stop-play ()
(interactive)
(kill-douban-music-process)
)
(defun douban-music-play-next-song ()
(interactive)
(kill-douban-music-process)
(douban-music-play-song)
)
(defun kill-douban-music-process ()
" kill all sydio process, ie. process name matchs
\"sydio-proc<?[0-9]*>?\"
"
(dolist (elt (process-list))
(if (string-match "douban-music-proc<?[0-9]*>?" (process-name elt))
(delete-process elt))))
(defun douban-music-current-song-info ()
(interactive)
(
princ current-song
)
)
(global-set-key (kbd "C-c p") 'douban-music-play-next-song)
(global-set-key (kbd "C-c P") 'douban-music-stop-play)
(provide 'douban-music)