Twitch API - Как получить текущую трансляцию по названию канала? (PHP)

Mex-Vision

Бессмертный
Iron Lord
Победитель в номинации 2022
Победитель в номинации 2021
Победитель в номинации 2020
Победитель в номинации 2019
Победитель в номинации 2017
Сообщения
829
Розыгрыши
0
Репутация
448
Реакции
539
Баллы
1 613
Всем привет, пытаюсь сделать небольшой модуль для трансляций, а именно, мониторинг каналов и отображения активных трансляций на них. С YouTube все успешно получилось, а вот Twitch дает мне под зад уже пол дня.

Я постоянно натыкаюсь на отсутcвие авторизации, пытался разобраться в документации, но всё безуспешно, так как примеров на PHP практически нет, а если и есть, то работают они со старым API которое уже не работает (kraken).

Мне необходимо получать:
- Название канала
- Аватарку стримера (канала)
- Статус текущей трансляции
- Название текущей трансляции

Буду очень благодарен за небольшой пример использования Twitch API.
 

@Mex-Vision, вот небольшой пример
PHP:
<?php

ini_set( 'display_errors', '1' );
error_reporting( E_ALL );

class TwitchApiV5
{
    const KRAKEN_URL    = 'https://api.twitch.tv/kraken';
    // регистрируем приложение и получаем ключи тут - https://dev.twitch.tv/console/apps/
    const CLIENT_ID        = 'xxxxx';
    const CLIENT_SECRET    = 'xxxx';
    
    private $curl = null;
    
    public function __construct()
    {
        $this->curl  = curl_init();
    }
    
    /**
     * @link https://dev.twitch.tv/docs/v5/reference/streams/#get-live-streams
     */
    public function getStreams( array $arr = null )
    {
        $parameters = $this->_parseArray( $arr );

        $url = self::KRAKEN_URL . '/streams' . $parameters;
        
        curl_setopt_array( $this->curl, [
                CURLOPT_URL            => $url,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_TIMEOUT        => 1,
                CURLOPT_HTTPHEADER     => [
                    'Accept: application/vnd.twitchtv.v5+json',
                    'Client-ID: ' . self::CLIENT_ID
                ]
            ]
        );

        return json_decode( curl_exec( $this->curl ), true );
    }
    
    private function _parseArray( array $arr = null )
    {
        $parameters = '';

        if ( $arr )
        {
            $parameters = '?';
            $lastValue = end( $arr );
            $endKey = key( $arr );
            foreach ( $arr as $key => $value )
            {
                $parameters .= $key . '=' . $value . ( $key == $endKey ? '' : '&' );
            }
        }

        return $parameters;
    }
    
    public function __destruct()
    {
        if ( !is_null( $this->curl ) )
        {
            curl_close( $this->curl );
        }
    }
}

$api = new TwitchApiV5();

echo '<pre>';
print_r( $api->getStreams( [ 'limit' => 100, 'offset' => 0, 'game' => rawurlencode( 'Lineage 2' ) ] ) );
echo '</pre>';

результат
Код:
Array
(
    [streams] => Array
        (
            [0] => Array
                (
                    [_id] => 43710028412
                    [game] => Lineage 2
                    [broadcast_platform] => live
                    [community_id] =>
                    [community_ids] => Array
                        (
                        )

                    [viewers] => 197
                    [video_height] => 1080
                    [average_fps] => 60
                    [delay] => 0
                    [created_at] => 2021-11-04T11:06:21Z
                    [is_playlist] =>
                    [stream_type] => live
                    [preview] => Array
                        (
                            [small] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-80x45.jpg
                            [medium] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-320x180.jpg
                            [large] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-640x360.jpg
                            [template] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-{width}x{height}.jpg
                        )

                    [channel] => Array
                        (
                            [mature] =>
                            [status] => Play with me on top essence server | DISCORD (info)
                            [broadcaster_language] => en
                            [broadcaster_software] =>
                            [display_name] => multiworld_essencel2
                            [game] => Lineage 2
                            [language] => ru
                            [_id] => 729604925
                            [name] => multiworld_essencel2
                            [created_at] => 2021-09-26T09:37:34.918005Z
                            [updated_at] => 2021-11-04T16:24:56.638883Z
                            [partner] =>
                            [logo] => https://static-cdn.jtvnw.net/jtv_user_pictures/61ca7622-5420-48a7-b9bf-61e0ce9297e7-profile_image-300x300.png
                            [video_banner] =>
                            [profile_banner] =>
                            [profile_banner_background_color] =>
                            [url] => https://www.twitch.tv/multiworld_essencel2
                            [views] => 623
                            [followers] => 3
                            [broadcaster_type] =>
                            [description] =>
                            [private_video] =>
                            [privacy_options_enabled] =>
                        )

                )

            [1] => Array
                (
                    [_id] => 44310870541
                    [game] => Lineage 2
                    [broadcast_platform] => live
                    [community_id] =>
                    [community_ids] => Array
                        (
                        )

                    [viewers] => 183
                    [video_height] => 1080
                    [average_fps] => 60
                    [delay] => 0
                    [created_at] => 2021-11-04T14:50:54Z
                    [is_playlist] =>
                    [stream_type] => live
                    [preview] => Array
                        (
                            [small] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-80x45.jpg
                            [medium] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-320x180.jpg
                            [large] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-640x360.jpg
                            [template] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-{width}x{height}.jpg
                        )

                    [channel] => Array
                        (
                            [mature] => 1
                            [status] => [LIVE] ДК на Мейне | Бесплатные Плюшки на Кач при регистрации по ссылке 4ga.me/axterial мейн версия | Розыгрыши 7д ПА в discord.gg/axterial
                            [broadcaster_language] => ru
                            [broadcaster_software] =>
                            [display_name] => Axterial
                            [game] => Lineage 2
                            [language] => en
                            [_id] => 49435579
                            [name] => axterial
                            [created_at] => 2013-09-25T10:50:39.796028Z
                            [updated_at] => 2021-11-04T16:26:17.831476Z
                            [partner] =>
                            [logo] => https://static-cdn.jtvnw.net/jtv_user_pictures/axterial-profile_image-d7f86ffdd63749e3-300x300.jpeg
                            [video_banner] => https://static-cdn.jtvnw.net/jtv_user_pictures/8ee3550b27d7de15-channel_offline_image-1920x1080.png
                            [profile_banner] =>
                            [profile_banner_background_color] =>
                            [url] => https://www.twitch.tv/axterial
                            [views] => 412686
                            [followers] => 4800
                            [broadcaster_type] =>
                            [description] => Бонусы при регистрации нового аккаунта http://4ga.me/axterial (только для мейн версии)
                            [private_video] =>
                            [privacy_options_enabled] =>
                        )

                )

        )

)

достаем нужные данные из полученного массива // profit!
 
@Mex-Vision, вот небольшой пример
PHP:
<?php

ini_set( 'display_errors', '1' );
error_reporting( E_ALL );

class TwitchApiV5
{
    const KRAKEN_URL    = 'https://api.twitch.tv/kraken';
    // регистрируем приложение и получаем ключи тут - https://dev.twitch.tv/console/apps/
    const CLIENT_ID        = 'xxxxx';
    const CLIENT_SECRET    = 'xxxx';
   
    private $curl = null;
   
    public function __construct()
    {
        $this->curl  = curl_init();
    }
   
    /**
     * @link https://dev.twitch.tv/docs/v5/reference/streams/#get-live-streams
     */
    public function getStreams( array $arr = null )
    {
        $parameters = $this->_parseArray( $arr );

        $url = self::KRAKEN_URL . '/streams' . $parameters;
       
        curl_setopt_array( $this->curl, [
                CURLOPT_URL            => $url,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_TIMEOUT        => 1,
                CURLOPT_HTTPHEADER     => [
                    'Accept: application/vnd.twitchtv.v5+json',
                    'Client-ID: ' . self::CLIENT_ID
                ]
            ]
        );

        return json_decode( curl_exec( $this->curl ), true );
    }
   
    private function _parseArray( array $arr = null )
    {
        $parameters = '';

        if ( $arr )
        {
            $parameters = '?';
            $lastValue = end( $arr );
            $endKey = key( $arr );
            foreach ( $arr as $key => $value )
            {
                $parameters .= $key . '=' . $value . ( $key == $endKey ? '' : '&' );
            }
        }

        return $parameters;
    }
   
    public function __destruct()
    {
        if ( !is_null( $this->curl ) )
        {
            curl_close( $this->curl );
        }
    }
}

$api = new TwitchApiV5();

echo '<pre>';
print_r( $api->getStreams( [ 'limit' => 100, 'offset' => 0, 'game' => rawurlencode( 'Lineage 2' ) ] ) );
echo '</pre>';

результат
Код:
Array
(
    [streams] => Array
        (
            [0] => Array
                (
                    [_id] => 43710028412
                    [game] => Lineage 2
                    [broadcast_platform] => live
                    [community_id] =>
                    [community_ids] => Array
                        (
                        )

                    [viewers] => 197
                    [video_height] => 1080
                    [average_fps] => 60
                    [delay] => 0
                    [created_at] => 2021-11-04T11:06:21Z
                    [is_playlist] =>
                    [stream_type] => live
                    [preview] => Array
                        (
                            [small] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-80x45.jpg
                            [medium] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-320x180.jpg
                            [large] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-640x360.jpg
                            [template] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-{width}x{height}.jpg
                        )

                    [channel] => Array
                        (
                            [mature] =>
                            [status] => Play with me on top essence server | DISCORD (info)
                            [broadcaster_language] => en
                            [broadcaster_software] =>
                            [display_name] => multiworld_essencel2
                            [game] => Lineage 2
                            [language] => ru
                            [_id] => 729604925
                            [name] => multiworld_essencel2
                            [created_at] => 2021-09-26T09:37:34.918005Z
                            [updated_at] => 2021-11-04T16:24:56.638883Z
                            [partner] =>
                            [logo] => https://static-cdn.jtvnw.net/jtv_user_pictures/61ca7622-5420-48a7-b9bf-61e0ce9297e7-profile_image-300x300.png
                            [video_banner] =>
                            [profile_banner] =>
                            [profile_banner_background_color] =>
                            [url] => https://www.twitch.tv/multiworld_essencel2
                            [views] => 623
                            [followers] => 3
                            [broadcaster_type] =>
                            [description] =>
                            [private_video] =>
                            [privacy_options_enabled] =>
                        )

                )

            [1] => Array
                (
                    [_id] => 44310870541
                    [game] => Lineage 2
                    [broadcast_platform] => live
                    [community_id] =>
                    [community_ids] => Array
                        (
                        )

                    [viewers] => 183
                    [video_height] => 1080
                    [average_fps] => 60
                    [delay] => 0
                    [created_at] => 2021-11-04T14:50:54Z
                    [is_playlist] =>
                    [stream_type] => live
                    [preview] => Array
                        (
                            [small] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-80x45.jpg
                            [medium] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-320x180.jpg
                            [large] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-640x360.jpg
                            [template] => https://static-cdn.jtvnw.net/previews-ttv/live_user_axterial-{width}x{height}.jpg
                        )

                    [channel] => Array
                        (
                            [mature] => 1
                            [status] => [LIVE] ДК на Мейне | Бесплатные Плюшки на Кач при регистрации по ссылке 4ga.me/axterial мейн версия | Розыгрыши 7д ПА в discord.gg/axterial
                            [broadcaster_language] => ru
                            [broadcaster_software] =>
                            [display_name] => Axterial
                            [game] => Lineage 2
                            [language] => en
                            [_id] => 49435579
                            [name] => axterial
                            [created_at] => 2013-09-25T10:50:39.796028Z
                            [updated_at] => 2021-11-04T16:26:17.831476Z
                            [partner] =>
                            [logo] => https://static-cdn.jtvnw.net/jtv_user_pictures/axterial-profile_image-d7f86ffdd63749e3-300x300.jpeg
                            [video_banner] => https://static-cdn.jtvnw.net/jtv_user_pictures/8ee3550b27d7de15-channel_offline_image-1920x1080.png
                            [profile_banner] =>
                            [profile_banner_background_color] =>
                            [url] => https://www.twitch.tv/axterial
                            [views] => 412686
                            [followers] => 4800
                            [broadcaster_type] =>
                            [description] => Бонусы при регистрации нового аккаунта http://4ga.me/axterial (только для мейн версии)
                            [private_video] =>
                            [privacy_options_enabled] =>
                        )

                )

        )

)

достаем нужные данные из полученного массива // profit!
Спасибо за пример, попробую и отпишусь. Вопрос: kraken вообще работает сейчас? А то у меня при попытке запроса к нему выдавало что-то в духе "устаревший api иди зубри документацию оО".
 
@Mex-Vision, скорее всего передается не верный заголовок (не та версия апи или еще что)
Код:
Accept: application/vnd.twitchtv.v5+json

вот метод получения данных по айди канала для ранее представленного класса
PHP:
class TwitchApiV5
{
     ...
     /**
     * @link https://dev.twitch.tv/docs/v5/reference/streams/#get-stream-by-user
     */
    public function getStream( $channel = '', array $arr = null )
    {
        $parameters = $this->_parseArray( $arr );
        
        $url = self::KRAKEN_URL . '/streams/' . $channel . $parameters;

        curl_setopt_array( $this->curl, [
                CURLOPT_URL            => $url,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_TIMEOUT        => 1,
                CURLOPT_HTTPHEADER     => [
                    'Accept: application/vnd.twitchtv.v5+json',
                    'Client-ID: ' . self::CLIENT_ID
                ]
            ]
        );
        
        return json_decode( curl_exec( $this->curl ), true );
    }
    ...
}

$api = new TwitchApiV5();

echo '<pre>';
print_r( $api->getStream( '729604925' ) );
echo '</pre>';

результат
Код:
Array
(
    [stream] => Array
        (
            [_id] => 43710028412
            [game] => Lineage 2
            [broadcast_platform] => live
            [community_id] =>
            [community_ids] => Array
                (
                )

            [viewers] => 201
            [video_height] => 1080
            [average_fps] => 60
            [delay] => 0
            [created_at] => 2021-11-04T11:06:21Z
            [is_playlist] =>
            [stream_type] => live
            [preview] => Array
                (
                    [small] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-80x45.jpg
                    [medium] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-320x180.jpg
                    [large] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-640x360.jpg
                    [template] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-{width}x{height}.jpg
                )

            [channel] => Array
                (
                    [mature] =>
                    [status] => Play with me on top essence server | DISCORD (info)
                    [broadcaster_language] => en
                    [broadcaster_software] =>
                    [display_name] => multiworld_essencel2
                    [game] => Lineage 2
                    [language] => ru
                    [_id] => 729604925
                    [name] => multiworld_essencel2
                    [created_at] => 2021-09-26T09:37:34.918005Z
                    [updated_at] => 2021-11-04T16:57:05.13631Z
                    [partner] =>
                    [logo] => https://static-cdn.jtvnw.net/jtv_user_pictures/61ca7622-5420-48a7-b9bf-61e0ce9297e7-profile_image-300x300.png
                    [video_banner] =>
                    [profile_banner] =>
                    [profile_banner_background_color] =>
                    [url] => https://www.twitch.tv/multiworld_essencel2
                    [views] => 629
                    [followers] => 3
                    [broadcaster_type] =>
                    [description] =>
                    [private_video] =>
                    [privacy_options_enabled] =>
                )

        )

)

представленные результаты с только что сделанных запросов этим скриптом, так что кракен работает
 
@Mex-Vision, скорее всего передается не верный заголовок (не та версия апи или еще что)
Код:
Accept: application/vnd.twitchtv.v5+json

вот метод получения данных по айди канала для ранее представленного класса
PHP:
class TwitchApiV5
{
     ...
     /**
     * @link https://dev.twitch.tv/docs/v5/reference/streams/#get-stream-by-user
     */
    public function getStream( $channel = '', array $arr = null )
    {
        $parameters = $this->_parseArray( $arr );
       
        $url = self::KRAKEN_URL . '/streams/' . $channel . $parameters;

        curl_setopt_array( $this->curl, [
                CURLOPT_URL            => $url,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_TIMEOUT        => 1,
                CURLOPT_HTTPHEADER     => [
                    'Accept: application/vnd.twitchtv.v5+json',
                    'Client-ID: ' . self::CLIENT_ID
                ]
            ]
        );
       
        return json_decode( curl_exec( $this->curl ), true );
    }
    ...
}

$api = new TwitchApiV5();

echo '<pre>';
print_r( $api->getStream( '729604925' ) );
echo '</pre>';

результат
Код:
Array
(
    [stream] => Array
        (
            [_id] => 43710028412
            [game] => Lineage 2
            [broadcast_platform] => live
            [community_id] =>
            [community_ids] => Array
                (
                )

            [viewers] => 201
            [video_height] => 1080
            [average_fps] => 60
            [delay] => 0
            [created_at] => 2021-11-04T11:06:21Z
            [is_playlist] =>
            [stream_type] => live
            [preview] => Array
                (
                    [small] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-80x45.jpg
                    [medium] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-320x180.jpg
                    [large] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-640x360.jpg
                    [template] => https://static-cdn.jtvnw.net/previews-ttv/live_user_multiworld_essencel2-{width}x{height}.jpg
                )

            [channel] => Array
                (
                    [mature] =>
                    [status] => Play with me on top essence server | DISCORD (info)
                    [broadcaster_language] => en
                    [broadcaster_software] =>
                    [display_name] => multiworld_essencel2
                    [game] => Lineage 2
                    [language] => ru
                    [_id] => 729604925
                    [name] => multiworld_essencel2
                    [created_at] => 2021-09-26T09:37:34.918005Z
                    [updated_at] => 2021-11-04T16:57:05.13631Z
                    [partner] =>
                    [logo] => https://static-cdn.jtvnw.net/jtv_user_pictures/61ca7622-5420-48a7-b9bf-61e0ce9297e7-profile_image-300x300.png
                    [video_banner] =>
                    [profile_banner] =>
                    [profile_banner_background_color] =>
                    [url] => https://www.twitch.tv/multiworld_essencel2
                    [views] => 629
                    [followers] => 3
                    [broadcaster_type] =>
                    [description] =>
                    [private_video] =>
                    [privacy_options_enabled] =>
                )

        )

)

представленные результаты с только что сделанных запросов этим скриптом, так что кракен работает
К сожалению нет(

The v5 API is deprecated and will be shutdown on February 28, 2022. Applications that have not accessed v5 before July 15, 2021 no longer have access to v5. For more information on the v5 API shutdown plan, see and the Twitch API documentation at .

1636047088077.png
 
@Mex-Vision, :unsure: ну да, помечен устаревшим
но работает же еще, и будет работать до 28 февраля 2022. Потом придется переписывать)
Он работает только у тех, кто создал свое "приложение" до определенного времени (July 15, 2021). Так что пошел я зубрить API=)
 
Пользуйся, мне не жалко))
*** Скрытый текст не может быть процитирован. ***
Спасибо, но я уже решил проблему, тесты заработали, сейчас доведу код до ума и выложу сюда, возможно кому-то пригодится.
 
Решил проблему благодаря ответам в данной теме, Google Translate и документации Twitch Api.

Алгоритм действий для таких чайников как я:
1) Регистрируем приложение -
2) CLIENT_ID - Перейдите в свое приложение, там будет поле "Идентификатор клиента" - это он и есть.
3) CLIENT_SECRET - Перейдите в свое приложение, там будет кнопка "Новый секретный код", после нажатие вы его увидите.
4) Метод _getAccessToken получает токкен для авторизации, который в дальнейшем используется в заголовке запроса.

Документация для тех кто будет допиливать код:

Примитивный класс для работы с Twitch Api.

PHP:
class TwitchApi
{
    const HELIX_URL    = 'https://api.twitch.tv/helix';

    // Регистрируем приложение и получаем ключи тут - https://dev.twitch.tv/console/apps/
    const CLIENT_ID        = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
    const CLIENT_SECRET    = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

    private $curl = null;

    public function __construct()
    {
        $this->curl = curl_init();
    }

    /**
     * @link https://dev.twitch.tv/docs/api/reference#get-streams
     */

    public function getStreams( array $arr = null )
    {
        $url = self::HELIX_URL . '/streams?' . http_build_query($arr,"", null, PHP_QUERY_RFC3986);
        return $this->_curl_exec($url);
    }

    /**
     * @link https://dev.twitch.tv/docs/api/reference#get-channel-information
     */

    public function getChannel(array $arr = null)
    {
        $url = self::HELIX_URL . '/channels?' . http_build_query($arr,"", null, PHP_QUERY_RFC3986);
        return $this->_curl_exec($url);
    }
  
    private function _curl_exec(string $url)
    {
        curl_setopt_array( $this->curl, [
                CURLOPT_URL            => $url,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_TIMEOUT        => 1,
                CURLOPT_HTTPHEADER     => [
                    'Authorization: Bearer ' . $this->_getAccessToken(),
                    'Client-Id: ' . self::CLIENT_ID
                ]
            ]
        );

        return json_decode( curl_exec( $this->curl ), true );
    }

    private function _getAccessToken()
    {
        $url = 'https://id.twitch.tv/oauth2/token';
        $data = array('client_id' => self::CLIENT_ID, 'client_secret' => self::CLIENT_SECRET, 'grant_type' => 'client_credentials');

        $options = array(
            'http' => array(
                'header' => "Content-type: application/x-www-form-urlencoded\r\n",
                'method' => 'POST',
                'content' => http_build_query($data)
            )
        );

        $context = stream_context_create($options);
        $result = json_decode(file_get_contents($url, false, $context), true );

        return $result['access_token'];
    }

    public function __destruct()
    {
        if(!is_null($this->curl))
            curl_close($this->curl);
    }
}

Результат выполнения метода getStreams(['user_login' => 'weplaycsgo_ru']):

1636057594723.png

PS: Спасибо

òbiòbi верифицированный пользователь.

=)
 
По топу что вы писали, похоже на oauth
Там должен быть лайфтайм токена, чтобы вы каждый раз не получали аксес токен ( но это не точно)
 
По топу что вы писали, похоже на oauth
Там должен быть лайфтайм токена, чтобы вы каждый раз не получали аксес токен ( но это не точно)
Да, он есть. Можно доработать код конечно же)
 
Назад
Сверху Снизу