Check-in [59075dcc1b]
Overview
| Comment: | Apply proper file extension to temp files (they're never cleaned up, are they?) Fix MIME type probing, strip attributes. Support Apple M3U minor type, detect GVP playlists. |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | action-mapfmts |
| Files: | files | file ages | folders |
| SHA1: |
59075dcc1b794f69604ed60cb7b9452c |
| User & Date: | mario on 2015-04-10 11:56:40 |
| Other Links: | branch diff | manifest | tags |
Context
|
2015-04-10
| ||
| 13:50 | Implement filename update in SaveAs dialog on changing FileFilter (.m3u, .pls, .xspf) extension. check-in: 0a9cb60b3a user: mario tags: action-mapfmts | |
| 11:56 | Apply proper file extension to temp files (they're never cleaned up, are they?) Fix MIME type probing, strip attributes. Support Apple M3U minor type, detect GVP playlists. check-in: 59075dcc1b user: mario tags: action-mapfmts | |
| 11:55 | SurfMusik actually holds .m3u playlists. check-in: 46062ce00f user: mario tags: action-mapfmts | |
Changes
Modified action.py from [666f98e53e] to [a1f8b1c311].
| ︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# Streamlink/listformat mapping
listfmt_t = {
"audio/x-scpls": "pls",
"audio/x-mpegurl": "m3u",
"audio/mpegurl": "m3u",
"video/x-ms-asf": "asx",
"application/xspf+xml": "xspf",
"*/*": "href", # "href" for unknown responses
"url/direct": "srv",
"url/youtube": "href",
"url/http": "href",
"audio/x-pn-realaudio": "ram",
| > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# Streamlink/listformat mapping
listfmt_t = {
"audio/x-scpls": "pls",
"audio/x-mpegurl": "m3u",
"audio/mpegurl": "m3u",
"application/vnd.apple.mpegurl": "m3u",
"video/x-ms-asf": "asx",
"application/xspf+xml": "xspf",
"*/*": "href", # "href" for unknown responses
"url/direct": "srv",
"url/youtube": "href",
"url/http": "href",
"audio/x-pn-realaudio": "ram",
|
| ︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
("smil", r""" <smil[^>]*> .* <seq> """),
("html", r""" <(audio|video)\b[^>]+\bsrc\s*=\s*["']?https?:// """),
("wpl", r""" <\?wpl \s+ version="1\.0" \s* \?> """),
("b4s", r""" <WinampXML> """), # http://gonze.com/playlists/playlist-format-survey.html
("jspf", r""" ^ \s* \{ \s* "playlist": \s* \{ """),
("asf", r""" ^ \[Reference\] .*? ^Ref\d+= """),
("json", r""" "url": \s* "\w+:// """),
("href", r""" .* """),
]
# Exec wrapper
#
| > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
("smil", r""" <smil[^>]*> .* <seq> """),
("html", r""" <(audio|video)\b[^>]+\bsrc\s*=\s*["']?https?:// """),
("wpl", r""" <\?wpl \s+ version="1\.0" \s* \?> """),
("b4s", r""" <WinampXML> """), # http://gonze.com/playlists/playlist-format-survey.html
("jspf", r""" ^ \s* \{ \s* "playlist": \s* \{ """),
("asf", r""" ^ \[Reference\] .*? ^Ref\d+= """),
("json", r""" "url": \s* "\w+:// """),
("gvp", r""" ^gvp_version:1\.\d+$ """),
("href", r""" .* """),
]
# Exec wrapper
#
|
| ︙ | ︙ | |||
245 246 247 248 249 250 251 |
return [url]
elif dest in ("srv", "href"):
return urls
debug( urls )
# Otherwise convert to local file
if local_file:
| | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
return [url]
elif dest in ("srv", "href"):
return urls
debug( urls )
# Otherwise convert to local file
if local_file:
fn, is_unique = tmp_fn(cnt, dest)
with open(fn, "wb") as f:
debug(dbg.DATA, "exporting with format:", dest, " into filename:", fn)
f.write( save_playlist(source="srv", multiply=True).export(urls=urls, dest=dest, title=title) )
return [fn]
else:
return urls
|
| ︙ | ︙ | |||
269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
if not len(r.headers):
return ("srv", r)
except:
return ("srv", None)
# Extract payload
mime = r.headers.get("content-type", "href")
# Map MIME to abbr type (pls, m3u, xspf)
if listfmt_t.get(mime):
mime = listfmt_t.get(mime)
# Raw content (mp3, flv)
elif mediafmt_t.get(mime):
debug(dbg.ERR, "Got media MIME type for expected playlist", mime, " on url=", url)
mime = mediafmt_t.get(mime)
| > | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
if not len(r.headers):
return ("srv", r)
except:
return ("srv", None)
# Extract payload
mime = r.headers.get("content-type", "href")
mime = mime.split(";")[0].strip()
# Map MIME to abbr type (pls, m3u, xspf)
if listfmt_t.get(mime):
mime = listfmt_t.get(mime)
# Raw content (mp3, flv)
elif mediafmt_t.get(mime):
debug(dbg.ERR, "Got media MIME type for expected playlist", mime, " on url=", url)
mime = mediafmt_t.get(mime)
|
| ︙ | ︙ | |||
444 445 446 447 448 449 450 |
global xmlentities
from xml.sax.saxutils import escape as xmlentities
return xmlentities(s)
# generate filename for temporary .m3u, if possible with unique id
| | | | 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 |
global xmlentities
from xml.sax.saxutils import escape as xmlentities
return xmlentities(s)
# generate filename for temporary .m3u, if possible with unique id
def tmp_fn(pls, ext="m3u"):
# use shoutcast unique stream id if available
stream_id = re.search("http://.+?/.*?(\d+)", pls, re.M)
stream_id = stream_id and stream_id.group(1) or "XXXXXX"
try:
channelname = main.current_channel
except:
channelname = "unknown"
return (str(conf.tmp) + os.sep + "streamtuner2."+channelname+"."+stream_id+"."+ext, len(stream_id) > 3 and stream_id != "XXXXXX")
|