-
Notifications
You must be signed in to change notification settings - Fork 1
/
twitchtv.php
149 lines (142 loc) · 4.82 KB
/
twitchtv.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
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
99
100
101
102
103
104
105
106
107
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
142
143
144
145
146
147
148
149
<?php
/*
Twitch.tv live streams playlist downloader
(HTML5 and Flash players lags so much)
(c) SysTools 2017-2024
http://systools.losthost.org/
https://github.com/systoolz/miscsoft/
Windows native application "TwitchXP.exe" can be downloaded here:
http://systools.losthost.org/?misc#twitchxp
Changelog:
2024.08.05 updated JSON code in playlist request
2022.12.28 old API has been removed, new implementation
2021.10.02 included JSON data validation
2021.07.08 replaced fsockopen() with stream_socket_client() because of PHP 5.6.0+:
fsockopen(): Peer certificate CN=`usher.ttvnw.net' did not match
expected CN=`usher.twitch.tv' in twitchtv.php on line 41
2019.01.06 add rawurlencode() since it was required for some args;
removed replace_pattern() and replaced with sprintf()
2018.05.23 Twitch.tv switched protocols from HTTP to HTTPS
2017.01.08 first publice release
AGDQ/SGDQ
https://gamesdonequick.com/schedule
https://player.twitch.tv/?volume=1&channel=gamesdonequick
*/
function get_page_from_web($link, $data = '', $auth = array()) {
$CRLF = chr(13).chr(10);
$type = 'tcp://';
$port = '80';
if (!strcasecmp(substr($link, 0, 7), 'http://')) {
$link = substr($link, 7);
}
if (!strcasecmp(substr($link, 0, 8), 'https://')) {
$link = substr($link, 8);
$type = 'ssl://';
$port = '443';
}
$host = substr($link, 0, strpos($link, '/'));
$link = substr($link, strpos($link, '/'));
$wp = '';
$context = stream_context_create(
array('ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
))
);
$fp = stream_socket_client($type.$host.':'.$port, $errno, $errstr, 15, STREAM_CLIENT_CONNECT, $context);
if ($fp) {
$out =
(empty($data) ? 'GET' : 'POST').' '.$link.' HTTP/1.0'.$CRLF.
'Host: '.$host.$CRLF.
(empty($auth) ? '' : implode($CRLF, $auth).$CRLF).
(empty($data) ? '' :
'Content-Length: '.strlen($data).$CRLF.
'Content-Type: text/plain; charset=UTF-8'.$CRLF
).
'Connection: Close'.$CRLF.
$CRLF.
$data;
fwrite($fp, $out);
while (!feof($fp)) {
$wp .= fgets($fp, 10 * 1024);
}
fclose($fp);
$fp = $CRLF.$CRLF;
$out = strpos($wp, $fp);
if ($out !== false) {
$wp = substr($wp, $out + strlen($fp));
}
}
return($wp);
}
function get_twich_playlist($channel) {
$result = '';
if (!empty($channel)) {
$channel = rawurlencode($channel);
// get clientId
$token = get_page_from_web('https://www.twitch.tv/'.$channel);
$auth = array();
preg_match('/clientId\s*=\s*"([0-9a-z]+)/is', $token, $auth);
$auth = array(
'Client-ID: '.array_pop($auth), // required
'Device-ID: '.substr(md5(strval(time())), 0, 16) // anything
);
// get query string
$link = array();
preg_match('/var\s+query\s*=\s*\'([^\']+)\'/is', $token, $link);
$link = html_entity_decode(array_pop($link), ENT_NOQUOTES, 'UTF-8');
$token = array(
'operationName' => 'PlaybackAccessToken_Template',
'query' => $link,
'variables' => array(
'isLive' => true,
'login' => $channel,
'isVod' => false,
'vodID' => '',
'playerType' => 'site',
'platform' => 'web'
)
);
// get token
$token = trim(get_page_from_web('https://gql.twitch.tv/gql', json_encode($token), $auth));
if (!empty($token)) {
$token = json_decode($token, true);
if (
(json_last_error() == JSON_ERROR_NONE) && (is_array($token)) &&
(array_key_exists('data', $token)) && (is_array($token['data'])) &&
(array_key_exists('streamPlaybackAccessToken', $token['data']))
) {
// usher.twitch.tv
$link = sprintf(
'https://usher.ttvnw.net/api/channel/hls/%s.m3u8?'.
'acmb=%s'.
'&allow_source=true'.
'&fast_bread=true'.
'&p=%u'.
'&play_session_id=%s'.
'&player_backend=mediaplayer'.
'&playlist_include_framerate=true'.
'&reassignments_supported=true'.
'&sig=%s'.
'&supported_codecs=avc1'.
'&token=%s'.
'&cdm=wv'.
'&player_version=1.16.0',
$channel,
rawurlencode(base64_encode('{}')), // empty array
time(),
md5(strval(time())), // anything
rawurlencode($token['data']['streamPlaybackAccessToken']['signature']),
rawurlencode($token['data']['streamPlaybackAccessToken']['value'])
);
$result = get_page_from_web($link);
}
}
}
return($result);
}
/*
// example of usage:
file_put_contents('playlist.m3u', get_twich_playlist('gamesdonequick'));
*/