Máte kanál na twitch.tv a zajímalo by vás, kolikátý je podle počtu diváků na české scéně celkově a také podle hry? Chcete mít toto číslo viditelné na streamu? Nebo jako příkaz pro Nightbota?
Zjištění pořadí na Twitch.tv
Když si na stránce https://www.twitch.tv/directory/all/cs necháte zobrazit síťový přenos v konzoli, tak zjistíte, že stránka si výpis kanálů načítá přes AJAX v JSON formátu z následující adresy:
https://streams.twitch.tv/kraken/streams?limit=20&offset=0&language_filters=&broadcaster_language=cs&on_site=1
Na této adrese najdeme seznam kanálů v českém jazyce. Problém je, že je stránkovaný s maximem 100 záznamů na stránku. Potřebujeme tedy vytvořit script, který bude umět následující věci:
- Stáhnout informace o všech českých kanálech a zjistit jejich počet
- Zjistit pozici našeho kanálu
- Zjistit kolik kanálů vysílá stejnou hru, jako náš kanál
- Zjistit pozici dle aktuální hry našeho kanálu
1) Informace o všech českých kanálech a jejich počet
Vytvoříme si v PHP třídu Twitch a v ní metodu load(), která nám načte všechny české kanály a metodu count(), která vrátí jejich počet :
class Twitch
{
// pole vsech streamu
private $streams = array();
// max. pocet kanalu v twitch API
private $limit = 100;
// stahne data z API
public function load($offset=0)
{
$url = sprintf('https://streams.twitch.tv/kraken/streams?limit=%d&offset=%d&language_filters=&broadcaster_language=cs&on_site=1', $this->limit, $offset);
$data = file_get_contents($url);
if ($data)
{
$json = json_decode($data, true);
if ($json)
{
// pridame vsechny kanaly do promenne $this->streams
if (!empty($json['streams']))
$this->streams = array_merge($this->streams, $json['streams']);
// pokud existuje dalsi stranka, tak nacteme i jeji kanaly
if ($json['_total']>($offset+$this->limit))
$this->load($offset+$this->limit);
}
}
}
// celkovy pocet kanalu
public function count() { return count($this->streams); }
// vsechny kanaly
public function getStreams() { return $this->streams; }
}
2) Pozice našeho kanálu
Když máme stažené všechny kanály, tak není problém najít ten náš. Vytvoříme si funkci findPosition($channel), která nám vrátí pozici našeho kanálu:
public function findPosition($channel)
{
foreach($this->getStreams() as $k=>$stream)
{
if ($stream['channel']['name']==$channel)
{
return $k+1;
}
}
return '?';
}
3) Kolik kanálů vysílá stejnou hru, jako náš kanál
Opět jednoduchá funkce, která projde všechny kanály a vrátí počet těch, které vysílají stejnou hru, jako náš kanál:
public function countTotalGames($channel)
{
$games = array();
$key = null;
foreach($this->getStreams() as $k=>$stream)
{
$games[$stream['game']][] = $stream['channel']['name'];
if ($stream['channel']['name']==$channel)
{
$key = $stream['game'];
}
}
return isset($games[$key]) ? count($games[$key]) : 0;
}
4) Pozice našeho kanálu v rámci vysílané hry
Poslední funkce, která je téměř totožná s funkcí předchozí:
public function findPositionByGame($channel)
{
$games = array();
foreach($this->getStreams() as $k=>$stream)
{
$games[$stream['game']][] = $stream['channel']['name'];
if ($stream['channel']['name']==$channel)
{
return count($games[$stream['game']]);
}
}
return '?';
}
Kompletní kód
<?php
header('Content-type: text/plain;charset=utf-8');
class Twitch
{
// pole vsech streamu
private $streams = array();
// max. pocet kanalu v twitch API
private $limit = 100;
// stahne data z API
public function load($offset=0)
{
$url = sprintf('https://streams.twitch.tv/kraken/streams?limit=%d&offset=%d&language_filters=&broadcaster_language=cs&on_site=1', $this->limit, $offset);
$data = file_get_contents($url);
if ($data)
{
$json = json_decode($data, true);
if ($json)
{
// pridame vsechny kanaly do promenne $this->streams
if (!empty($json['streams']))
$this->streams = array_merge($this->streams, $json['streams']);
// pokud existuje dalsi stranka, tak nacteme i jeji kanaly
if ($json['_total']>($offset+$this->limit))
$this->load($offset+$this->limit);
}
}
}
// celkovy pocet kanalu
public function count() { return count($this->streams); }
// vsechny kanaly
public function getStreams() { return $this->streams; }
// najde celkovou pozici kanalu
public function findPosition($channel)
{
foreach($this->getStreams() as $k=>$stream)
{
if ($stream['channel']['name']==$channel)
{
return $k+1;
}
}
return '?';
}
// najde pozici podle hry
public function findPositionByGame($channel)
{
$games = array();
foreach($this->getStreams() as $k=>$stream)
{
$games[$stream['game']][] = $stream['channel']['name'];
if ($stream['channel']['name']==$channel)
{
return count($games[$stream['game']]);
}
}
return '?';
}
// pocet kanalu, ktere hraji stejnou hru, jako kanal $channel
public function countTotalGames($channel)
{
$games = array();
$key = null;
foreach($this->getStreams() as $k=>$stream)
{
$games[$stream['game']][] = $stream['channel']['name'];
if ($stream['channel']['name']==$channel)
{
$key = $stream['game'];
}
}
return isset($games[$key]) ? count($games[$key]) : 0;
}
}
if (!empty($_GET['channel']))
{
$twitch = new Twitch();
$twitch->load();
printf("Celkem: %d/%d Hra: %d/%d", $twitch->findPosition($_GET['channel']), $twitch->count(), $twitch->findPositionByGame($_GET['channel']), $twitch->countTotalGames($_GET['channel']));
}
else
{
printf('Celkem: kanal nevysila :(');
}
?>
Když si kód spustíme, výsledek bude vypadat např. takto:
Celkem: 72/161 Hra: 1/2
Použití
Pokud vás přestane bavit stránku refreshovat v prohlížeči, můžete vyzkoušet následující možnosti:
Příkaz do Nightbota
Pokud tento kód nasadíte na web, není problém pro Nigthbota vytvořit příkaz !rank, jehož obsahem bude $(urlfetch http://www.example.com/twitch_position.php?channel=$(channel)).
Do OBS
Pokud chcete mít na streamu pořád vidět, jak na tom váš kanál je, není problém využít CLR browser, který se používá např. pro Twitchalerts, Streamtip atd. Jde o plugin, který umí přidat do scény obsah webové stránky. Bylo by ale nutné zajistit, aby se adresa pravidelně obnovovala. K tomu by např. stačilo upravit kód tak, aby nezobrazoval pouze text/plain, ale text/html s příslušnými tagy a meta http-equiv=“refresh“.