StatHistoryController.class.php 4.25 KB
<?php
/**
 * 获取腾讯云直播播放情况
 * Created by PhpStorm.
 * User: zhoutao
 * Date: 2018/2/5
 * Time: 上午10:19
 */

namespace Frontend\Controller\Callback;

use Com\LiveSDK;
use Common\Common\Constant;
use Common\Model\CronModel;
use Common\Service\CronService;
use Common\Service\MainService;
use Common\Service\StudioService;
use Common\Service\StudioStatService;
use VcySDK\Cron;
use VcySDK\Service;

class StatHistoryController extends AbstractController
{
    public function Index()
    {
        $streamId = $this->callBackData['streamId'];

        $studioServ = new StudioService();
        $mainServ = new MainService();

        // 因为直播码会重复 所以获取最新的一条
        $studioDetail = $studioServ->get_by_conds(['stream_id' => $streamId], ['created' => 'DESC']);
        $mainDetail = $mainServ->get($studioDetail['lm_id']);
        // 如果直播已经没了 或者 结束 还是接受到了通知 则关闭 UC 计划任务
        if (empty($mainDetail) || $mainDetail['live_status'] == Constant::LIVE_STATUS_OVER) {
            // 关闭计划任务
            $cronServ = new CronService();
            $cronSdk = new Cron(Service::instance());
            $cronDetail = $cronServ->get_by_conds([
                'lm_id' => $mainDetail['lm_id'],
                'type' => CronModel::TYPE_LIVE_STAT_HISTORY
            ]);
            // 删除计划任务
            try {
                if (!empty($cronDetail['cron_id'])) {
                    $cronSdk->delete($cronDetail['cron_id']);
                }
            } catch (\Exception $e) {
                // 不处理
            }
        }

        // 获取播放历史
        $liveSdk = new LiveSDK();
        $statHistory = $liveSdk->getLiveStat($streamId);
        if (empty($statHistory['output']['stream_info'])) {
            exit('SUCCESS');
        }
        // 推流瞬时数据
        $streamInfo = array_shift($statHistory['output']['stream_info']);
        // 记录瞬时统计数据
        $studioStatServ = new StudioStatService();
        $studioStatServ->insert([
            'stream_id' => $streamInfo['stream_name'],
            // Mbps = Kbps * 1000
            'bandwidth' => $streamInfo['bandwidth'] * 1000,
            'online' => $streamInfo['online'],
            'client_ip' => $streamInfo['client_ip'],
            'server_ip' => $streamInfo['server_ip'],
            'fps' => $streamInfo['fps'],
            'speed' => $streamInfo['speed'],
        ]);

        // FIXME 腾讯云统计的好像偏高 先注释了
//        $redis = new \Redis();
//        $redis->connect(cfg('REDIS_HOST'), cfg('REDIS_PORT'));
//        if (cfg('REDIS_PWD')) {
//            $redis->auth(cfg('REDIS_PWD'));
//        }
//        // 获取锁
//        $redLock = new DistributedRedisLock([$redis], 500, 10);
//        $lock = $redLock->lock('Live_' . $studioDetail['lm_id'] . '_Lock_Update_Peak', 2000);
//
//        // 获取 Redis 内的峰值
//        $redisKeyNamePeak = 'Live_' . $studioDetail['lm_id'] . '_PEAK';
//        $peakMemberNum = $redis->get($redisKeyNamePeak) ?: $mainDetail['online_peak'];
//
//        // 腾讯云那的在线人数
//        $onlineNumber = $streamInfo['online'] ?: 0;
//        // 如果超过了本地峰值 则扣减并发人数
//        if ($onlineNumber > $peakMemberNum) {
//            // 更新本地峰值
//            $redis->set($redisKeyNamePeak, $onlineNumber, Constant::PEAK_SURVIVAL_TIME);
//            // 释放锁
//            $redLock->unlock($lock);
//
//            // 扣减并发人数
//            $orderUtil = new Order();
//            $orderUtil->LiveCaseExpend([
//                'liveCastId' => $studioDetail['stream_id'],
//                'lcelSpendAmout' => $onlineNumber - $peakMemberNum,
//                // 强制扣减
//                'forceConsum' => true
//            ]);
//
//            // 当前峰值改为腾讯云在线人数
//            $peakMemberNum = $onlineNumber;
//        } else {
//            // 释放锁
//            $redLock->unlock($lock);
//        }
//
//
//        // 把 Redis 里的峰值放入数据库
//        if ($peakMemberNum > ($mainDetail['online_peak'] ?: 0)) {
//            $mainServ->update($mainDetail['lm_id'], ['online_peak' => $peakMemberNum]);
//        }

        exit('SUCCESS');
    }
}