Aktuální pořadí kanálu na Twitch.tv podle počtu diváků

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:

  1. Stáhnout informace o všech českých kanálech a zjistit jejich počet
  2. Zjistit pozici našeho kanálu
  3. Zjistit kolik kanálů vysílá stejnou hru, jako náš kanál
  4. 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“.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *