-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstream.php
145 lines (122 loc) · 7.53 KB
/
stream.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
<?php
// session_start();
@define("main_dir", __DIR__ . '/');
require_once __DIR__ . '/masterking_app/loader.php';
use Chrisyue\PhpM3u8\Facade\ParserFacade;
use Chrisyue\PhpM3u8\Stream\TextStream;
if(empty($_SERVER['HTTP_HOST']) || empty($_SERVER['REQUEST_SCHEME']))
{
respondWithJSON('Request is not valid!');
}
header("Access-Control-Allow-Origin: https://{$_SERVER['HTTP_HOST']}");
header("Access-Control-Allow-Headers: X-Requested-With");
header('Access-Control-Max-Age: 86400');
$isApple = isApple();
if(empty($_GET['username']) || is_array($_GET['username']))
{
respondWithJSON('User not exits!');
}
$username = strtolower(GetCleanInput($_GET['username']));
$result = $database->select('streamers', ['id', 'is_relay', 'username', 'master_playlist', 'master_lastcheck', 'quality_url' , 'isLive'], ['username' => $username]);
if (empty($result[0]['is_relay']) || empty($result[0]['isLive'])) {
respondWithJSON('Streamer is not live or does not exist!');
}
$user_data = $result[0];
$username = GetCleanInput(strtolower($user_data['username']));
if(!empty($user_data['quality_url']) && !empty($user_data['master_playlist']))
{
$ip = GetUserIP();
if(!empty($ip) /*&& !empty($_SESSION['imRead'])*/ && !$database->has('stream_viewers', ['user_ip' => $ip , 'streamer' => $username]))
{
$database->insert('stream_viewers', ['attempt' => 1, 'check_date' => date("Y-m-d H:i:s"), 'streamer' => $username, 'user_ip' => $ip]);
}
header("Content-type: application/vnd.apple.mpegurl");
$m3u8_url = str_replace("IRTWDOMAIN", $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'], $user_data['master_playlist']);
echo $isApple ? str_replace('.php', '.m3u8', $m3u8_url) : $m3u8_url;
exit();
}
if(!empty($user_data['master_lastcheck']) && strtotime($user_data['master_lastcheck']) + 30 > time())
{
respondWithJSON('Streamer is not live!');
}
SetLastMasterCheck($user_data['id']);
$token_resp = getTokenSignature($username, user_agent, TWITCH_ORIGINAL_CLIENTID);
if(empty($token_resp) || empty($token_resp['value']) || empty($token_resp['signature'])) {
respondWithJSON('Streamer is not live!');
}
$streamPlaybackAccessToken= urlencode(str_replace('\\', '', rtrim(trim(json_encode($token_resp['value']), '"'), '"')));
$signature = $token_resp['signature'];
$twitch_master_m8u3 = "https://usher.ttvnw.net/api/channel/hls/" . $username. ".m3u8?allow_source=true&fast_bread=true&p=" . time()*10 ."&play_session_id=" . md5(time() . rand(1,9999999999)) . "&player_backend=mediaplayer&playlist_include_framerate=true&reassignments_supported=true&sig=" . $signature . "&supported_codecs=avc1&token=" . $streamPlaybackAccessToken . "&cdm=wv&player_version=1.11.0";
$master_response = curl_request($twitch_master_m8u3, ["headers" => ['User-Agent: ' . user_agent]]);
if(empty($master_response) || strlen($master_response) < 50 || strpos($master_response, 'transcode_does_not_exist') > 0) {
// $database->update("streamers", ['isLive' => 0, 'twitch_viewers' => 0, 'stream_viewers' => 0, 'quality_url' => '', 'master_playlist' => '', 'playlist_cache' => ''], [
// "id" => $user_data['id']
// ]);
respondWithJSON('Streamer is not live!');
}
try{
$parser = new ParserFacade();
$media_meta = $parser->parse(new TextStream($master_response));
} catch(Exception $e) {
respondWithJSON('Streamer is not live!');
}
if(empty($media_meta['EXT-X-MEDIA']))
{
respondWithJSON('Streamer is not live!');
}
$new_m3u8 = '#EXTM3U' . "\n";
$new_m3u8 .= '#EXT-X-MASTERKING-INFO:SERVICE-BY:"Amin.MasterkinG"';
$QUALITY_URL = [];
if(count($media_meta['EXT-X-MEDIA']) == 1)
{
$quality = $media_meta['EXT-X-MEDIA'][0];
$new_m3u8 .= "\n" . '#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="' . $quality['GROUP-ID'] . '",NAME="' . $quality['NAME'] . '",AUTOSELECT=YES,DEFAULT=YES';
$array_ID = 0;
$BANDWIDTH = $media_meta['EXT-X-STREAM-INF'][$array_ID]['BANDWIDTH'];
$CODECS = $media_meta['EXT-X-STREAM-INF'][$array_ID]['CODECS'];
$VIDEO = $media_meta['EXT-X-STREAM-INF'][$array_ID]['VIDEO'];
$FRAMERATE = $media_meta['EXT-X-STREAM-INF'][$array_ID]['FRAME-RATE'];
$RESOLUTION = $media_meta['EXT-X-STREAM-INF'][$array_ID]['RESOLUTION']->__toString();
$QUALITY_URL[$VIDEO] = $media_meta['EXT-X-STREAM-INF'][$array_ID]['uri'];
$new_m3u8 .= "\n" . "#EXT-X-STREAM-INF:BANDWIDTH=" . $BANDWIDTH . ',RESOLUTION=' . $RESOLUTION . ',CODECS="' . $CODECS . '",VIDEO="' . $VIDEO . '",FRAME-RATE=' . $FRAMERATE;
$new_m3u8 .= "\nIRTWDOMAIN/live_streams/playlist/" . $username . '.php?quality=' . $VIDEO;
} else {
$exists_quality = [];
foreach($media_meta['EXT-X-MEDIA'] as $array_ID => $quality) {
// if((strpos($quality['NAME'], '720') !== false || strpos($quality['NAME'], '480') !== false || strpos($quality['NAME'], '360') !== false) && empty($exists_quality[$media_meta['EXT-X-STREAM-INF'][$array_ID]['RESOLUTION']->getHeight()]))
// if((strpos($quality['NAME'], '720') !== false || strpos($quality['NAME'], '480') !== false) && empty($exists_quality[$media_meta['EXT-X-STREAM-INF'][$array_ID]['RESOLUTION']->getHeight()]))
// if((strpos($quality['NAME'], '720') !== false || strpos($quality['NAME'], '160') !== false/* || strpos($quality['NAME'], '480') !== false*/|| strpos($quality['NAME'], '360') !== false) && empty($exists_quality[$media_meta['EXT-X-STREAM-INF'][$array_ID]['RESOLUTION']->getHeight()]))
if((strpos($quality['NAME'], '720') !== false || strpos($quality['NAME'], '160') !== false || strpos($quality['NAME'], '480') !== false || strpos($quality['NAME'], '360') !== false) && empty($exists_quality[$media_meta['EXT-X-STREAM-INF'][$array_ID]['RESOLUTION']->getHeight()]))
{
$exists_quality[$media_meta['EXT-X-STREAM-INF'][$array_ID]['RESOLUTION']->getHeight()] = 1;
$new_m3u8 .= "\n" . '#EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="' . $quality['GROUP-ID'] . '",NAME="' . $quality['NAME'] . '",AUTOSELECT=YES,DEFAULT=YES';
$BANDWIDTH = $media_meta['EXT-X-STREAM-INF'][$array_ID]['BANDWIDTH'];
$CODECS = $media_meta['EXT-X-STREAM-INF'][$array_ID]['CODECS'];
$VIDEO = $media_meta['EXT-X-STREAM-INF'][$array_ID]['VIDEO'];
$FRAMERATE = $media_meta['EXT-X-STREAM-INF'][$array_ID]['FRAME-RATE'];
$RESOLUTION = $media_meta['EXT-X-STREAM-INF'][$array_ID]['RESOLUTION']->__toString();
$QUALITY_URL[$VIDEO] = $media_meta['EXT-X-STREAM-INF'][$array_ID]['uri'];
$new_m3u8 .= "\n" . "#EXT-X-STREAM-INF:BANDWIDTH=" . $BANDWIDTH . ',RESOLUTION=' . $RESOLUTION . ',CODECS="' . $CODECS . '",VIDEO="' . $VIDEO . '",FRAME-RATE=' . $FRAMERATE;
$new_m3u8 .= "\nIRTWDOMAIN/live_streams/playlist/" . $username . '.php?quality=' . $VIDEO;
}
}
}
$database->update("streamers", [
"quality_url" => json_encode($QUALITY_URL),
"master_playlist" => $new_m3u8
], [
"id" => $user_data['id']
]);
if(!empty($_GET['playlist']))
{
header('location: ' . $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . '/live_streams/playlist/' . $username . '.php?quality=' . GetCleanInput($_GET['playlist']));
exit();
}
header("Content-type: application/vnd.apple.mpegurl");
$m3u8_url = str_replace("IRTWDOMAIN", $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'], $new_m3u8);
echo $isApple ? str_replace('.php', '.m3u8', $m3u8_url) : $m3u8_url;
$ip = GetUserIP();
if(!empty($ip) /*&& !empty($_SESSION['imRead'])*/ && !$database->has('stream_viewers', ['user_ip' => $ip , 'streamer' => $username]))
{
$database->insert('stream_viewers', ['attempt' => 1, 'check_date' => date("Y-m-d H:i:s"), 'streamer' => $username, 'user_ip' => $ip]);
}