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
|
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
|
-
+
+
-
+
-
-
+
+
+
+
+
+
+
+
|
# api: streamtuner2
# title: File browser
# description: Displays mp3/oggs or m3u/pls files from local media file directories.
# type: channel
# category: local
# version: 0.3.2
# version: 0.4.5
# priority: optional
# status: unsupported
# depends: python:mutagen, python:id3
# config:
# { name: file_browser_dir, type: text, value: "$XDG_MUSIC_DIR, ~/MP3", description: "List of directories to scan for audio files." },
# { name: file_browser_ext, type: text, value: "mp3,ogg, m3u,pls,xspf, avi,flv,mpg,mp4", description: "File type/extension filter." },
# { name: file_browser_converttourl, type: bool, value: 1, description: "Convert file path to 'file:///' style URL" } },
# url: http://freshcode.club/projects/streamtuner2
# png:
# iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wUFDQsK23vYngAAA6lJREFUOMtFz8tu1FYAxvH/sc+xxx7bM8lkElAgISoV4qIgpEaomwg2bMqiQmo3lfowPElVVbQr3gBVqGJRGi6VEERFDROS0Ewmc/N47Bkf+7gLevke4Kfv
# L374/vufxm/ffjnudJQoisoVonLDcN+sr39z7uXLXzfOn6cRhmSTCf3TUwa9HoN+H601ynXxwhA7ivhdCH48PkZOut0vdh48cKtej9C2iSyLsF7/xLpx4/5eu/1LZzSiaQx1z8O5cIHapUvVmpRkaUqcJMRpSjydmnEcP/2zKH6WOs/7mdZBVVXIqsKuKk4nE4qdnTueUncCpZh5HoHj4AqBVRQIrUFrLGPwlaLhOLiWtX93OPxKIuX+0HHWJ5ZF03VxpaRfFLRmM1rTKUGrRX1piUYQEIUhfhRRC0OqOMZxHIIwJIgiHFj77OnT+7KEd0Wt
# tl0Kgev7NHyf5apCTSaoLEMlCZdu3uT85ib1hQWi1VWcMCTb3cXxPJxmExlF2LWaMFpvS4TYcx2nmpalsKoKJQSNMCQ6cwZPCMxgwKTbpfPoETWlWDx3jtblyyghEFpjSYmwbYQx6DyPJUJ0bKUKU5Yqn83QSqGVolQKGQSEGxssrK3RffyY6Zs3zK9epb6wgBWGCCFQjkOlFFVRoIfDkTRwYIRIDTR0nqPnc7RSFP/AhW2jfJ/WlSvQ7zPe3SU9OECdPYuwbUrXxSiFsW2KOB7IaZYdp3keV9DQ8znacSj+RaWkqtVACExR0NrcZPriBflw
# SJqmWO32R9BxMEAxnfatJE37cZb1jWVRaP3x4XxOkecIy0J6HibPmY1GqHqdpa0tbNdlvLNDfnJCOR5jJhPMYECZpj2JlPEwSbqBEFTG/Jd85fZtNm/dIjk6Itnbw19e5tN79yiHQ5JnzxgfHDBrNvGjCOM4lElCkWWn1ufb2/M4TQ9LIQAoiwJTlrQ3NrCVQjoOw04Hf2UF5ftI3wchsOt1Zu/eoTsd9KtX5E+eYCaTnux2u1VRVe8N/y/PMn57+JBka4v04IDs8JDD+RxGI8RoxPz1a6yyJJ/PGT9/rivXzZRSp3m9/kYAtFdWvm3PZt+1
# kkQEtk1g2wRSEihV+badR7Va2vS8ceR5A9uYrimKv/LZ7MhU1VF7efnD2sWL3cb6+slzrT9IgKXFxT8W07S33GpZywsLHxzLep/Gcac3Gu0H9fp7Z3X1KLp27WT9+vXh8epq8vXdu7N+FPG61UIXBXZZAmCVJX8DADze5LjPkMQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTUtMDUtMDVUMTU6MTA6NTkrMDI6MDBD/PY6AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE1LTA1LTA1VDE1OjEwOjU5KzAyOjAwMqFOhgAAAABJRU5ErkJggg==
# png-orig:
# https://openclipart.org/detail/168001/folder-icon-red-music
# extraction-method: os
#
# Local file browser. Presents files from configured directories.
# This is not what streamtuner2 is meant for. Therefore this is
# This is not what Streamtuner2 is meant for. Therefore this is
# an optional plugin, and not overly well integrated.
#
# Bugs:
# Only loads directories on startup. Doesn't work when post-activated
# per pluginmanager2 for instance. And LANG=C breaks it on startup,
# if media directories contain anything but ASCII filenames.
#from __future__ import print_function
#
# Currently does not play files with UTF characters on Windows.
#
# If your player doesn't play local files try unchecking "Convert file path to 'file:///' style URL". (Might happen on Windows when not using VLC.exe).
# When using VLC however it must be checked.
#
# After checking/unchecking restart Streamtuner2 for recollecting the local files.
# modules
import os
import re
from channels import *
from config import *
|
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
+
+
|
# prepare
def __init__(self, parent):
# data dirs
self.dir = [self.env_dir(s) for s in conf.file_browser_dir.split(",")]
self.ext = [s.strip() for s in conf.file_browser_ext.split(",")]
# first run
if not "file_browser_converttourl" in conf:
conf.file_browser_converttourl = 1
if not self.categories or not self.streams:
self.scan_dirs()
# draw gtk lists
ChannelPlugin.__init__(self, parent)
# make editable
|
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
|
-
-
+
+
+
+
+
+
-
+
-
-
+
+
-
+
-
+
+
-
+
-
-
+
+
+
|
# extract meta data
def file_entry(self, fn, dir):
# basic data
url = ("%s/%s" % (dir, fn))
url = url.replace("\\", "/")
# if conf.windows: # needed for VLC playback
url = url.replace(" ", "%20")
if conf.file_browser_converttourl:
url = url.replace(" ", "%20")
if url.startswith("/"):
url = "file://" + url
else:
url = "file:///" + url
meta = {
"title": "",
"filename": fn,
"url": "file:///"+url,
"url": url,
"genre": "",
"album": "",
"artist": "",
"length": "n/a",
"bitrate": 0,
# "format": mime_fmt(fn[-3:]),
"format": mime_fmt(fn[-(len(fn)-fn.rfind(".")-1):]),
"format": mime_fmt(self.fnext(fn)),
"editable": False,
}
# add ID3 tag infos
try:
streaminfo =get_meta(dir + "/" + fn)
streaminfo = get_meta(dir + "/" + fn)
# add streaminfo
if streaminfo.info: # no streaminfo.info, maybe ID3 available
try:
if not streaminfo.info.bitrate == 0:
meta.update({"bitrate": streaminfo.info.bitrate/1000})
except: #FLAC and M4A do not have bitrate property
pass
if not streaminfo.info.length == 0.0: #FLAC sometimes have it...
meta.update({"length": ddhhmmss(int(streaminfo.info.length))})
# add ID3
meta.update(mutagen_postprocess(streaminfo) or {})
except: # unsupported by Mutagen
except: # not supported by Mutagen
pass
return meta
# check fn for .ext
def we_like_that_extension(self, fn):
# return fn[-3:] in self.ext
return self.fnext(fn) in self.ext
return fn[-(len(fn)-fn.rfind(".")-1):] in self.ext
def fnext(self, fn):
return os.path.splitext(fn)[1][1:]
# same as init
def update_categories(self):
self.scan_dirs()
# same as init
def update_streams(self, cat, *k, **kw):
self.scan_dirs()
return self.streams.get(os.path.basename(cat))
|