Check-in [220ee1286a]
Overview
Comment: | Exchange audio/mp3 for standard audio/mpeg MIME type. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
220ee1286a7b08ab5b75daf426749b9e |
User & Date: | mario on 2014-05-13 21:00:06 |
Other Links: | manifest | tags |
Context
2014-05-13
| ||
21:04 | Mirror config dialog changes to Gtk3 ui file check-in: 74bf77f074 user: mario tags: trunk | |
21:00 | Exchange audio/mp3 for standard audio/mpeg MIME type. check-in: 220ee1286a user: mario tags: trunk | |
19:58 | Some surfmusik category fixes, support for TV channel retrieval check-in: 3e7da2fdba user: mario tags: trunk | |
Changes
Modified action.py from [a3c14ebdbb] to [5d3890f993].
︙ | ︙ | |||
37 38 39 40 41 42 43 | # but also "browser" for web URLs # class action: # streamlink formats lt = {"asx":"video/x-ms-asf", "pls":"audio/x-scpls", "m3u":"audio/x-mpegurl", "xspf":"application/xspf+xml", "href":"url/http", "ram":"audio/x-pn-realaudio", "smil":"application/smil"} # media formats | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # but also "browser" for web URLs # class action: # streamlink formats lt = {"asx":"video/x-ms-asf", "pls":"audio/x-scpls", "m3u":"audio/x-mpegurl", "xspf":"application/xspf+xml", "href":"url/http", "ram":"audio/x-pn-realaudio", "smil":"application/smil"} # media formats mf = {"mp3":"audio/mpeg", "ogg":"audio/ogg", "aac":"audio/aac"} # web @staticmethod def browser(url): __print__( dbg.CONF, conf.browser ) action.run(conf.browser + " " + action.quote(url)) |
︙ | ︙ | |||
59 60 61 62 63 64 65 | return str(s) # should actually be "\\\"%s\\\"" % s else: return "%r" % str(s) # calls player for stream url and format @staticmethod | | | | | | 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 | return str(s) # should actually be "\\\"%s\\\"" % s else: return "%r" % str(s) # calls player for stream url and format @staticmethod def play(url, audioformat="audio/mpeg", listformat="text/x-href"): if (url): url = action.url(url, listformat) if (audioformat): if audioformat == "audio/mp3": audioformat = "audio/mpeg" cmd = conf.play.get(audioformat, conf.play.get("*/*", "vlc %u")) __print__( dbg.PROC,"play", url, cmd ) try: action.run( action.interpol(cmd, url) ) except: pass # exec wrapper @staticmethod def run(cmd): if conf.windows: os.system("start \"%s\"") else: os.system(cmd + " &") # streamripper @staticmethod def record(url, audioformat="audio/mpeg", listformat="text/x-href", append="", row={}): __print__( dbg.PROC, "record", url ) cmd = conf.record.get(audioformat, conf.record.get("*/*", None)) try: action.run( action.interpol(cmd, url, row) + append ) except: pass # save as .m3u |
︙ | ︙ | |||
207 208 209 210 211 212 213 | # extract stream address from .pls URL if (re.search("\.pls", pls)): #audio/x-scpls return action.pls(pls) elif (re.search("\.asx", pls)): #video/x-ms-asf return re.findall("<Ref\s+href=\"(http://.+?)\"", http.get(pls)) elif (re.search("\.m3u|\.ram|\.smil", pls)): #audio/x-mpegurl return re.findall("(http://[^\s]+)", http.get(pls), re.I) | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | # extract stream address from .pls URL if (re.search("\.pls", pls)): #audio/x-scpls return action.pls(pls) elif (re.search("\.asx", pls)): #video/x-ms-asf return re.findall("<Ref\s+href=\"(http://.+?)\"", http.get(pls)) elif (re.search("\.m3u|\.ram|\.smil", pls)): #audio/x-mpegurl return re.findall("(http://[^\s]+)", http.get(pls), re.I) else: # just assume it was a direct mpeg/ogg streamserver link return [ (pls if pls.startswith("/") else http.fix_url(pls)) ] pass # generate filename for temporary .m3u, if possible with unique id @staticmethod def tmp_fn(pls): |
︙ | ︙ |
Modified channels/_generic.py from [3af550db05] to [e7ef47afa8].
︙ | ︙ | |||
48 49 50 51 52 53 54 | # desc module = "generic" title = "GenericChannel" homepage = "http://milki.inlcude-once.org/streamtuner2/" base_url = "" listformat = "audio/x-scpls" | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | # desc module = "generic" title = "GenericChannel" homepage = "http://milki.inlcude-once.org/streamtuner2/" base_url = "" listformat = "audio/x-scpls" audioformat = "audio/mpeg" # fallback value config = [] has_search = False # categories categories = ["empty", ] current = "" default = "empty" |
︙ | ︙ | |||
427 428 429 430 431 432 433 | # convert audio format nick/shortnames to mime types, e.g. "OGG" to "audio/ogg" def mime_fmt(self, s): # clean string s = s.lower().strip() # rename map = { | | | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | # convert audio format nick/shortnames to mime types, e.g. "OGG" to "audio/ogg" def mime_fmt(self, s): # clean string s = s.lower().strip() # rename map = { "audio/mp3":"audio/mpeg", # Note the real mime type is /mpeg, but /mp3 is more understandable in the GUI "ogg":"ogg", "ogm":"ogg", "xiph":"ogg", "vorbis":"ogg", "vnd.xiph.vorbis":"ogg", "mp3":"mpeg", "mp":"mpeg", "mp2":"mpeg", "mpc":"mpeg", "mps":"mpeg", "aac+":"aac", "aacp":"aac", "realaudio":"x-pn-realaudio", "real":"x-pn-realaudio", "ra":"x-pn-realaudio", "ram":"x-pn-realaudio", "rm":"x-pn-realaudio", # yes, we do video "flv":"video/flv", "mp4":"video/mp4", } map.update(action.action.lt) # list type formats (.m3u .pls and .xspf) if map.get(s): |
︙ | ︙ |
Modified channels/internet_radio_org_uk.py from [2ca4dac6b1] to [f41506948c].
︙ | ︙ | |||
108 109 110 111 112 113 114 | "url": url, "genre": self.strip_tags(genre), "homepage": http.fix_url(homepage), "title": title, "playing": playing, "bitrate": int(bitrate), "listeners": int(listeners if listeners else 0), | | | | 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 | "url": url, "genre": self.strip_tags(genre), "homepage": http.fix_url(homepage), "title": title, "playing": playing, "bitrate": int(bitrate), "listeners": int(listeners if listeners else 0), "format": "audio/mpeg", # there is no stream info on that, but internet-radio.org.uk doesn't seem very ogg-friendly anyway, so we assume the default here }) # DOM parsing else: # the streams are arranged in table rows doc = pq(html) for dir in (pq(e) for e in doc("tr.stream")): bl = dir.find("td[align=right]").text() bl = rx_numbers.findall(str(bl) + " 0 0") entries.append({ "title": dir.find("b").text(), "homepage": http.fix_url(dir.find("a.url").attr("href")), "url": dir.find("a").eq(2).attr("href"), "genre": dir.find("td").eq(0).text(), "bitrate": int(bl[0]), "listeners": int(bl[1]), "format": "audio/mpeg", "playing": dir.find("td").eq(1).children().remove().end().text()[13:].strip(), }) # next page? if str(page+1) not in rx_pages.findall(html): max = 0 else: |
︙ | ︙ |
Modified channels/punkcast.py from [e751e37b9b] to [0e12904925].
︙ | ︙ | |||
70 71 72 73 74 75 76 | #-- all from frontpage for uu in rx_link.findall(http.get(self.homepage)): (homepage, id, title) = uu entries.append({ "genre": "?", "title": title, "playing": "PUNKCAST #"+id, | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #-- all from frontpage for uu in rx_link.findall(http.get(self.homepage)): (homepage, id, title) = uu entries.append({ "genre": "?", "title": title, "playing": "PUNKCAST #"+id, "format": "audio/mpeg", "homepage": homepage, }) # done return entries |
︙ | ︙ |
Modified channels/timer.py from [57941064a8] to [5079381818].
︙ | ︙ | |||
162 163 164 165 166 167 168 | except: return 0 # no limit # action wrapper def play(self, row, *args, **kwargs): action.play( url = row["url"], | | | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | except: return 0 # no limit # action wrapper def play(self, row, *args, **kwargs): action.play( url = row["url"], audioformat = row.get("format","audio/mpeg"), listformat = row.get("listformat","url/direct"), ) # action wrapper def record(self, row, *args, **kwargs): #print("TIMED RECORD") # extra params duration = self.duration(row.get(self.timefield)) if duration: append = " -a %S.%d.%q -l "+str(duration*60) # make streamripper record a whole broadcast else: append = "" # start recording action.record( url = row["url"], audioformat = row.get("format","audio/mpeg"), listformat = row.get("listformat","url/direct"), append = append, ) def test(self, row, *args, **kwargs): print("TEST KRONOS", row) |
Modified cli.py from [ea53579a96] to [b62ad1b334].
︙ | ︙ | |||
105 106 107 108 109 110 111 | if row.get("url"): print(row["url"]) # run player def play(self, *args): row = self.stream(*args) if row.get("url"): | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | if row.get("url"): print(row["url"]) # run player def play(self, *args): row = self.stream(*args) if row.get("url"): #action.action.play(row["url"], audioformat=row.get("format","audio/mpeg")) self.plugins[self.current_channel].play(row) # return cache data 1:1 def dump(self, channel): c = self.channel(channel) c.cache() return c.streams |
︙ | ︙ |
Modified config.py from [9f0935794a] to [5e2372f9f1].
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | dirs = ["/usr/share/streamtuner2", "/usr/local/share/streamtuner2", sys.path[0], "."] self.share = [d for d in dirs if os.path.exists(d)][0] # settings from last session last = self.load("settings") if (last): self.update(last) # store defaults in file else: self.save("settings") self.firstrun = 1 # some defaults def defaults(self): self.browser = "sensible-browser" self.play = { | > | | 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 | dirs = ["/usr/share/streamtuner2", "/usr/local/share/streamtuner2", sys.path[0], "."] self.share = [d for d in dirs if os.path.exists(d)][0] # settings from last session last = self.load("settings") if (last): self.update(last) self.migrate() # store defaults in file else: self.save("settings") self.firstrun = 1 # some defaults def defaults(self): self.browser = "sensible-browser" self.play = { "audio/mpeg": "audacious ", # %u for url to .pls, %g for downloaded .m3u "audio/ogg": "audacious ", "audio/aac": "amarok -l ", "audio/x-pn-realaudio": "vlc --one-instance", "audio/*": "totem ", "*/*": "vlc --one-instance %srv", } self.record = { |
︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 188 189 | for key,value in with_new_data.items(): if type(value) == dict: self[key].update(value) else: self[key] = value # descends into sub-dicts instead of wiping them with subkeys # check for existing filename in directory list def find_in_dirs(self, dirs, file): for d in dirs: if os.path.exists(d+"/"+file): return d+"/"+file | > > > > > > > | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | for key,value in with_new_data.items(): if type(value) == dict: self[key].update(value) else: self[key] = value # descends into sub-dicts instead of wiping them with subkeys # update old setting names def migrate(self): # 2.1.1 if "audio/mp3" in self.play: self.play["audio/mpeg"] = self.play["audio/mp3"] del self.play["audio/mp3"] # check for existing filename in directory list def find_in_dirs(self, dirs, file): for d in dirs: if os.path.exists(d+"/"+file): return d+"/"+file |
︙ | ︙ |
Modified gtk2.xml from [17490ef6c9] to [99e1222436].
︙ | ︙ | |||
1214 1215 1216 1217 1218 1219 1220 | <property name="left_attach">1</property> <property name="right_attach">2</property> <property name="top_attach">12</property> <property name="bottom_attach">13</property> </packing> </child> <child> | | | 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 | <property name="left_attach">1</property> <property name="right_attach">2</property> <property name="top_attach">12</property> <property name="bottom_attach">13</property> </packing> </child> <child> <object class="GtkEntry" id="config_play_audio_mpeg"> <property name="width_request">200</property> <property name="height_request">20</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="invisible_char">●</property> <property name="invisible_char_set">True</property> <property name="primary_icon_activatable">False</property> |
︙ | ︙ | |||
1237 1238 1239 1240 1241 1242 1243 | <property name="bottom_attach">2</property> </packing> </child> <child> <object class="GtkLabel" id="label7"> <property name="visible">True</property> <property name="can_focus">False</property> | | > | 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 | <property name="bottom_attach">2</property> </packing> </child> <child> <object class="GtkLabel" id="label7"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">audio/mpeg</property> </object> <packing> <property name="top_attach">1</property> <property name="bottom_attach">2</property> </packing> </child> <child> |
︙ | ︙ |
Modified st2.py from [6bfb3a77f9] to [22d6d5d44f].
︙ | ︙ | |||
310 311 312 313 314 315 316 | self.channel().play(row) favicon.download_playing(row) # streamripper def on_record_clicked(self, widget): row = self.row() | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | self.channel().play(row) favicon.download_playing(row) # streamripper def on_record_clicked(self, widget): row = self.row() action.record(row.get("url"), "audio/mpeg", "url/direct", row=row) # browse stream def on_homepage_stream_clicked(self, widget): url = self.selected("homepage") action.browser(url) |
︙ | ︙ | |||
721 722 723 724 725 726 727 | main.channel().save() self.cancel(w) # add a new list entry, update window def new(self, w): s = main.channel().stations() | | | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 | main.channel().save() self.cancel(w) # add a new list entry, update window def new(self, w): s = main.channel().stations() s.append({"title":"new", "url":"", "format":"audio/mpeg", "genre":"", "listeners":1}); main.channel().switch() # update display main.channel().gtk_list.get_selection().select_path(str(len(s)-1)); # set cursor to last row self.open(w) # hide window def cancel(self, *w): |
︙ | ︙ | |||
766 767 768 769 770 771 772 | # set/load values between gtk window and conf. dict def apply(self, config, prefix="config_", save=0): for key,val in config.items(): # map non-alphanumeric chars from config{} to underscores in according gtk widget names id = re.sub("[^\w]", "_", key) w = main.get_widget(prefix + id) __print__(dbg.CONF, "config", ("save" if save else "load"), prefix+id, w, val) | | | 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 | # set/load values between gtk window and conf. dict def apply(self, config, prefix="config_", save=0): for key,val in config.items(): # map non-alphanumeric chars from config{} to underscores in according gtk widget names id = re.sub("[^\w]", "_", key) w = main.get_widget(prefix + id) __print__(dbg.CONF, "config", ("save" if save else "load"), prefix+id, w, val) # recurse into dictionaries, transform: conf.play.audio/mpeg => conf.play_audio_mpeg if (type(val) == dict): self.apply(val, prefix + id + "_", save) # load or set gtk.Entry text field elif (w and save and type(w)==gtk.Entry): config[key] = w.get_text() elif (w and type(w)==gtk.Entry): w.set_text(str(val)) |
︙ | ︙ |