Last active
April 12, 2020 18:02
-
-
Save ste-lam/5339ef566c94fcd8cb43 to your computer and use it in GitHub Desktop.
QND (dkjson: http://dkolf.de/src/dkjson-lua.fsl/home)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local json = require("dkjson") | |
local client = "jzkbprff40iqj646a697cyrvl0zt2m6" | |
local urls = { | |
vod = { | |
token = "${scheme}://api.twitch.tv/api/vods/${user}/access_token?client_id=${client}", | |
playlist = "${scheme}://usher.ttvnw.net/vod/${user}.m3u8?allow_source=true&allow_spectre=true&type=any&nauth=${token}&nauthsig=${sig}" | |
}, | |
hls = { | |
token = "${scheme}://api.twitch.tv/api/channels/${user}/access_token?client_id=${client}", | |
playlist = "${scheme}://usher.ttvnw.net/api/channel/hls/${user}.m3u8?allow_source=true&allow_spectre=true&type=any&token=${token}&sig=${sig}" | |
} | |
} | |
function ends_with(s, test) | |
return s:sub(-#test) == test | |
end | |
function begins_with(s, test) | |
return s:sub(1, #test) == test | |
end | |
function matches(begin) | |
return ends_with(("."..vlc.path.."/"):match("^([^/]+)/"), begin) | |
end | |
-- QND: hacked m3u-parser for twitch | |
function m3u_parse(url, meta) | |
local m3u_parse_line = function (line, map) | |
local tag, data = line:match("^#([^:]*:)(.*)") | |
for k, v in ("," .. data):gmatch("%s*,%s*([^=]+)=\"([^\"]*)\"") do | |
map[tag .. k] = v | |
end | |
end | |
local stream = vlc.stream(url) | |
if not stream then return false end | |
local items = {} | |
local map = {} | |
if "#EXTM3U" ~= stream:readline() then | |
return {{}} | |
end | |
while true do | |
local line = stream:readline() | |
if not line then break end | |
if "#" == line:sub(1, 1) then | |
m3u_parse_line(line, map) | |
else | |
local name = map["EXT-X-MEDIA:NAME"] or "error" | |
local resolution = map["EXT-X-STREAM-INF:RESOLUTION"] or "error" | |
table.insert(items, { | |
path = line, | |
description = meta.description, | |
name = name.." ("..resolution..")" | |
}) | |
map = {} | |
end | |
end | |
return items | |
end | |
function get_playlist(urls, id, meta) | |
local opt = {scheme = vlc.access, user = id, client = client} | |
local url = build_url(urls.token, opt) | |
local data = json.decode(vlc.stream(url):readline()) | |
opt.token = data.token | |
opt.sig = data.sig | |
url = build_url(urls.hls, opt) | |
return m3u_parse(url, meta) | |
end | |
function get_content(line, matcher, finder) | |
local content | |
if string.match( line, matcher ) then | |
_,_,content = string.find( line, finder ) | |
if content then | |
content = vlc.strings.resolve_xml_special_chars( content ) | |
end | |
end | |
return content | |
end | |
function build_url(template, options) | |
return template:gsub("%${(%w+)}", function (arg) | |
return vlc.strings.encode_uri_component(options[arg]) | |
end) | |
end | |
function probe() | |
return (vlc.access == "http" | |
or vlc.access == "https") | |
and matches(".twitch.tv") | |
end | |
function parse() | |
local meta = {} | |
local id | |
local path = vlc.path:match("^[^/]+/(.-)/?$") | |
while true do | |
-- ugly pseudo xml/html parsing | |
local line = vlc.readline() | |
if not line then break end | |
meta.title = get_content( line, "<meta.- property='og:title'>", "content='(.-)'" ) | |
meta.description = get_content( line, "<meta.- property='og:description'>", "content='(.-)'" ) | |
end | |
-- vod url | |
id = path:match("videos/([^/]+)$") | |
if id | |
then | |
return get_playlist(urls.vod, id, meta) | |
end | |
-- live stream url | |
id = path:match("^([^/]+)$") | |
if id | |
then | |
return get_playlist(urls.hls, id, meta) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment