SHOW:
|
|
- or go back to the newest paste.
1 | import urllib2 | |
2 | from cookielib import CookieJar | |
3 | from Crypto.Cipher import AES | |
4 | import argparse | |
5 | ||
6 | cj = CookieJar() | |
7 | agentACM = 'AppleCoreMedia/1.0.0.11D201 (iPhone; U; CPU OS 7_1_2 like Mac OS X; en_us)' | |
8 | openerACM = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) | |
9 | openerACM.addheaders = [('User-agent', agentACM)] | |
10 | ||
11 | def getUrl(url): | |
12 | response = openerACM.open(url) | |
13 | return response.read() | |
14 | ||
15 | def downloadM3U8(outFile,srcUrl=None,srcFile=None,baseUrl=None,key=None): | |
16 | if srcUrl: | |
17 | m3u8_data = getUrl(srcUrl) | |
18 | m3u8name = srcUrl.split('?')[0].split('/')[-1] | |
19 | parameters = srcUrl.split('?')[1] | |
20 | baseUrl = srcUrl.split('?')[0][:-1*len(m3u8name)] | |
21 | if srcFile: | |
22 | m3u8_data = open(srcFile, 'rb').read() | |
23 | decrypter = None | |
24 | fileObj = open(outFile, 'wb') | |
25 | for line in m3u8_data.split('\n'): | |
26 | if line.startswith('#EXT-X-KEY'): | |
27 | if 'METHOD=AES-128' in line: | |
28 | if 'URI=' in line: | |
29 | if key: | |
30 | keyValue = key | |
31 | else: | |
32 | keyUrl = line.split('URI="')[1].split('"')[0] | |
33 | keyValue = getUrl(keyUrl) | |
34 | if 'IV=' in line: | |
35 | iv = line.split('IV=0x')[1].decode('hex') | |
36 | else: | |
37 | iv = '00000000000000000000000000000000'.decode('hex') | |
38 | - | print 'KEY : %X' % keyValue |
38 | + | print 'KEY : %s' % keyValue.encode('hex') |
39 | - | print 'IV : %X' % iv |
39 | + | print 'IV : %s' % iv.encode('hex') |
40 | decrypter = AES.new(keyValue, AES.MODE_CBC, iv) | |
41 | if not line.startswith('#'): | |
42 | print line.split('?')[0].split('/')[-1] | |
43 | if baseUrl: | |
44 | if not (line.startswith('http://') or line.startswith('https://')): | |
45 | line = baseUrl+line | |
46 | data = getUrl(line) | |
47 | if decrypter: | |
48 | data = decrypter.decrypt(data) | |
49 | fileObj.write(data) | |
50 | fileObj.close() | |
51 | ||
52 | if __name__=="__main__": | |
53 | parser = argparse.ArgumentParser(description='Download-Decrypt M3U8') | |
54 | parser.add_argument('-i', dest='input', help='Input M3U8 Url or File', metavar='URL-FILE', required=True) | |
55 | parser.add_argument('-o', dest='outFile', help='Output TS File', metavar='FILE', required=True) | |
56 | parser.add_argument('-baseurl', dest='baseUrl', help='Base Url for input m3u8', metavar='URL') | |
57 | ||
58 | parser.add_argument('-key', dest='keyFile', help='Key File', metavar='FILE') | |
59 | parser.add_argument('-keyhex', dest='keyHex', help='Key in Hex', metavar='KEXHEX') | |
60 | ||
61 | args = parser.parse_args() | |
62 | ||
63 | if args.keyFile: key = open(args.keyFile, "rb").read() | |
64 | elif args.keyHex: key = args.keyHex.decode('hex') | |
65 | else: key = None | |
66 | ||
67 | if args.input.startswith('http://') or args.input.startswith('https://'): | |
68 | downloadM3U8(args.outFile,srcUrl=args.input,baseUrl=args.baseUrl,key=key) | |
69 | else: | |
70 | downloadM3U8(args.outFile,srcFile=args.input,baseUrl=args.baseUrl,key=key) |