如何获得 Twitch 观看时间如流元素

问题描述

我目前正在开发一个小 twitch.tv 聊天机器人。我知道,有大约一千个,但我想创建自己的,只是为了有一个项目 - 所以这不是重点。

我想知道如何计算用户的观看时长。就像streamelements.com 使用他们的!watchtime 聊天命令一样。我没有找到任何 API 端点来获取当前正在查看流的用户。唯一找到的是 https://dev.twitch.tv/docs/api/reference#get-streams 中的当前观看次数,但无法链接特定用户

有人知道吗?

解决方法

没有可以直接执行此操作的 API 端点。 但是,我最近用 PHP 做了类似的事情,不需要 Twitch API 凭据。我工作的频道使用 NightBot,因此我将尝试简要解释它是如何使用它的,这样您就可以随心所欲地实现它。 免责声明:我是 PHP 新手,所以它可能可以改进;此外,使用来自 Twitch API 的命令可能会改进代码。

该文件名为“watchtime.php”。在更新请求中,它获取聊天记录并将更新之间的时间差添加到每个用户的观看时间中。对于 get 请求,它会获取保存的观看时间,并以天、小时、分钟和秒为单位进行解析。

要更新频道的数据库,您必须使用调度程序或循环请求 https://path/to/watchtime.php?action=update&channel=target,其中 'target' 是频道名称。请求间隔必须少于 10 分钟。但是,如果只有频道正在流式传输,请确保执行请求。每个循环周期,脚本都会请求 Twitch TMI 获取聊天记录(例如 Ludwig https://tmi.twitch.tv/group/user/ludwig/chatters),然后将更新之间的时间差添加到每个聊天记录中。我将值存储在 JSON 中;对于您的聊天机器人,我建议实施一个真正的数据库。如果更新没有错误,响应文本将为“OK”。

为了从 NightBot 获取观看时间,我使用了命令 $(urlfetch https://path/to/watchtime.php?action=get&channel=$(channel)&user=$(user)&time=$(time)),其中 $(urlfetch url) 返回一个 url 的输出,$(channel) 是频道名,$(user) 是用户名,$(time) 是当前时间(对于PHP,但它用于绕过 NightBot 中的查询缓存)。 但是,我只计算观众和VIP的观看时间;对于模组,它会返回一个错误(可以更改)。

这是PHP代码:

<?php
if (!array_key_exists('channel',$_REQUEST)) {
    echo 'Empty channel';
    return;
}
if (!array_key_exists('action',$_REQUEST)) {
    echo 'Empty action (get/update)';
    return;
}

$channel = $_REQUEST['channel'];   // Channel username
$file = "{$channel}.watchtime.json";    // File with watchtime

// Open json and collect data
if (file_exists($file)) {
    $data = json_decode(file_get_contents($file),true);
} else {
    $data = [];
}
 if ($_REQUEST['action'] == 'update') {
    // Update watchtime (watchtime.php?channel=streamer&action=update)
    // Do an update only when the target is streaming!
    // You can also insert here a API call to verify it.

    $now = time();  // Epoch time
    if (array_key_exists('$',$data) && $now - $data['$'] < 600) {
        // Increment if only the last update has been made in less than 10 min.
        // This prevents increments when the stream is first loaded.

        // Fetch chatters
        $url = "http://tmi.twitch.tv/group/user/{$channel}/chatters";  // Don't use https here
        $users = json_decode(file_get_contents($url),true)['chatters'];

        // Lazy way to find if the stream is off
        if (empty($users['broadcaster'])) {
            echo 'Empty broadcaster';
            return;
        }

        // This script selects only vips ans viewers,mods watchtimes are not counted.
        $chatters = array_merge($users['vips'],$users['viewers']);
        // Increment watchtime
        $passed = $now - $data['$'];  // Time passed since last update
        foreach ($chatters as $viewer) {
            if (!array_key_exists($viewer,$data))
                $data[$viewer] = 0;
            $data[$viewer] += $passed;
        }
    }
    $data['$'] = $now;  // Store the epoch time of the update
    file_put_contents($file,json_encode($data));    // Save data
    echo "OK";

} elseif ($_REQUEST['action'] == 'get') {
    // Get watchtime of an user (watchtime.php?channel=streamer&action=get&user=username)

    if (empty($data)) {
        echo 'Empty watchtime,update it first!';
        return;
    }
    if (!array_key_exists('user',$_REQUEST)) {
        echo 'Empty username';
        return;
    }
    define("username",$_REQUEST['user']);
    if (array_key_exists(username,$data)) {
        $passed = time() - $data['$'];
        if ($passed > 600)
            $passed  = 0;
        // Both $data[username] and $passed are integers
        $s = $data[username] + $passed;

        // Parsing seconds to days,hours,mins,secs
        $m = intdiv($s,60);
        $s -= $m * 60;
        $h = intdiv($m,60);
        $m -= $h * 60;
        $d = intdiv($h,24);
        $h -= $d * 24;

        // Show times if only they are greater than zeros
        $args = [];
        if ($d > 0) array_push($args,"{$d} days");
        if ($h > 0) array_push($args,"{$h} hours");
        if ($m > 0) array_push($args,"{$m} minutes");
        if ($s > 0) array_push($args,"{$s} seconds");

        echo username . ' watched  the stream for ' . implode(',',$args) . '!';
    } else echo 'Invalid username "' . username . '": moderator,too new or nonexistent';
}