jtvrtmp.py
· 2.1 KiB · Python
Raw
# rtmpdump parameter generator for justin.tv/twitch.tv streams v3
# * Usage: jtvrtmp.py channelname [quality]
# where channelname is the channel name ([twitch/justin].tv/channelname)
# and quality is an optional parameter with a valid quality setting
# (360p, 480p, 720p, etc) If quality isn't present, it selects 360p.
# * if quality is live, it picks the quality setting with a +, which
# is a restream of the video being sent to jtv, no transcoding involved.
#
# Changelog:
# v3: Removed unicode copyright symbol
# v2: Added exception catching for when a stream is offline or the specified
# quality setting is unavailable.
# v1: Initial release
#
# Copyright 2013 Steven Smith (blha303). All Rights Reserved.
# New BSD license
# http://www.opensource.org/licenses/BSD-3-Clause
from urllib2 import urlopen
import json
from sys import argv, exit
def getswfaddr(channelname):
return urlopen("http://www.justin.tv/widgets/live_embed_player.swf?channel=" + channelname).geturl().split("&userAgent")[0]
def getstreaminfo(channelname):
data = json.loads(urlopen("http://usher.justin.tv/find/%s.json?type=any" % channelname.lower()).read())
newd = {}
for i in data:
newd[i['display']] = i
return newd
def buildcmdline(channelname, data, quality="360p"):
if quality == "live":
for i in data:
if "+" in i:
quality = i
try:
data = data[quality]
except KeyError:
return '; echo "-------------"; echo "Couldn\'t find stream info for %s, maybe the stream is offline?"; echo "-------------" #' % quality
if not "live-cdn" in data["connect"] and not "justintvlivefs" in data["connect"]:
justinlegacyparams = '-j "%s" ' % data["token"].replace('"', r'\"')
else:
justinlegacyparams = ""
out = '-r "%s/%s" %s--swfVfy "%s" -v -o -' % (data["connect"], data["play"], justinlegacyparams, getswfaddr(channelname))
return out
def main():
if len(argv) < 2:
print "Usage: %s channelname [quality]"
exit(2)
if len(argv) > 2:
quality = argv[2]
else:
quality = "360p"
channelname = argv[1]
data = getstreaminfo(channelname)
print buildcmdline(channelname, data, quality=quality)
if __name__ == "__main__":
main()
| 1 | # rtmpdump parameter generator for justin.tv/twitch.tv streams v3 |
| 2 | # * Usage: jtvrtmp.py channelname [quality] |
| 3 | # where channelname is the channel name ([twitch/justin].tv/channelname) |
| 4 | # and quality is an optional parameter with a valid quality setting |
| 5 | # (360p, 480p, 720p, etc) If quality isn't present, it selects 360p. |
| 6 | # * if quality is live, it picks the quality setting with a +, which |
| 7 | # is a restream of the video being sent to jtv, no transcoding involved. |
| 8 | # |
| 9 | # Changelog: |
| 10 | # v3: Removed unicode copyright symbol |
| 11 | # v2: Added exception catching for when a stream is offline or the specified |
| 12 | # quality setting is unavailable. |
| 13 | # v1: Initial release |
| 14 | # |
| 15 | # Copyright 2013 Steven Smith (blha303). All Rights Reserved. |
| 16 | # New BSD license |
| 17 | # http://www.opensource.org/licenses/BSD-3-Clause |
| 18 | |
| 19 | from urllib2 import urlopen |
| 20 | import json |
| 21 | from sys import argv, exit |
| 22 | |
| 23 | def getswfaddr(channelname): |
| 24 | return urlopen("http://www.justin.tv/widgets/live_embed_player.swf?channel=" + channelname).geturl().split("&userAgent")[0] |
| 25 | |
| 26 | def getstreaminfo(channelname): |
| 27 | data = json.loads(urlopen("http://usher.justin.tv/find/%s.json?type=any" % channelname.lower()).read()) |
| 28 | newd = {} |
| 29 | for i in data: |
| 30 | newd[i['display']] = i |
| 31 | return newd |
| 32 | |
| 33 | def buildcmdline(channelname, data, quality="360p"): |
| 34 | if quality == "live": |
| 35 | for i in data: |
| 36 | if "+" in i: |
| 37 | quality = i |
| 38 | try: |
| 39 | data = data[quality] |
| 40 | except KeyError: |
| 41 | return '; echo "-------------"; echo "Couldn\'t find stream info for %s, maybe the stream is offline?"; echo "-------------" #' % quality |
| 42 | if not "live-cdn" in data["connect"] and not "justintvlivefs" in data["connect"]: |
| 43 | justinlegacyparams = '-j "%s" ' % data["token"].replace('"', r'\"') |
| 44 | else: |
| 45 | justinlegacyparams = "" |
| 46 | out = '-r "%s/%s" %s--swfVfy "%s" -v -o -' % (data["connect"], data["play"], justinlegacyparams, getswfaddr(channelname)) |
| 47 | return out |
| 48 | |
| 49 | def main(): |
| 50 | if len(argv) < 2: |
| 51 | print "Usage: %s channelname [quality]" |
| 52 | exit(2) |
| 53 | if len(argv) > 2: |
| 54 | quality = argv[2] |
| 55 | else: |
| 56 | quality = "360p" |
| 57 | channelname = argv[1] |
| 58 | data = getstreaminfo(channelname) |
| 59 | print buildcmdline(channelname, data, quality=quality) |
| 60 | |
| 61 | if __name__ == "__main__": |
| 62 | main() |
| 63 |