• 用openresty(Lua)写一个获取YouTube直播状态的接口


    文章原发布于:https://www.chenxublog.com/2019/08/29/openresty-get-youtube-live-api.html

    之前在QQ机器人上面加了个虚拟主播开播提醒的功能(群261037783),我直接用caddy反代来获取YouTube页面的信息。由于是定时轮询一大堆人,而且是下载整个页面的内容,所以延迟极高。
    被某人调侃的群名:

    所以我决定写一个接口,直接由服务器来判断状态,并把结果传给机器人,这样会省下很多时间和流量。

    网页接口选择有不少,可以直接php,也可以搞python或者.net来写,不过经过多方面的考虑,我决定使用OpenResty来实现这个功能。

    OpenResty

    实际上这个反代就是在nginx的基础上,加上了Lua功能。也正是因为这样,我可以直接用Lua脚本来写一个接口,完全不需要使用后端的东西,而且资源占用极低。。

    开搞

    配置

    新建一个虚拟主机,往里面扔上自己lua脚本的设置:

    	#youtube接口
    	location /api {
    		default_type application/json;
    		content_by_lua_file /www/wwwroot/xxx.xxx.com/api.lua;
    	}
    

    然后去改这个脚本文件就好了

    安装lua依赖

    由于需要https下载功能来获取页面信息,我们直接用luarocks装两个东西就好了

    如果你没装过luarocks,请自行使用apt-get install luarocksyum install luarocks进行安装

    我们需要安装下面两个组件:

    luarocks install luaSec
    luarocks install httpclient
    

    然后还需要一个json库,随便找一个就好了,放到合适的目录下面,例如下载下面这个脚本:

    https://github.com/chenxuuu/receiver-meow/blob/master/appdata/lua/require/JSON.lua

    写功能

    写功能就很随意了,我现在写的是,传入一个c=xxx的值,xxx为频道号,返回开播信息的json信息即可:

    package.path = package.path..";/www/wwwroot/xxx.xxx.com/?.lua"
    --包位置,用来引用json库
    json = require("JSON")
    
    channel = ngx.req.get_uri_args()["c"]
    if not channel then ngx.say(json:encode({error = "no c found"})) return end
    
    hc = require('httpclient').new()
    res = hc:get("https://www.youtube.com/channel/"..channel.."/live")
    if not res.body then ngx.say(json:encode({error = res.err})) return end
    
    if ngx.req.get_uri_args()["debug"] == "on" then
    	ngx.say(res.body)
    	return
    end
    
    local ytplayer_config = res.body:match("ytplayer.config *= *(.-});")
    if not ytplayer_config then ngx.say(json:encode({error = "no this channel"})) return end
    local info = json:decode(json:decode(ytplayer_config)['args']['player_response'])
    
    local result = {}
    result.live = info.videoDetails.isLive
    result.title = info.videoDetails.title
    result.url = "https://youtu.be/"..info.videoDetails.videoId
    result.thumbnail = info.videoDetails.thumbnail.thumbnails[#info.videoDetails.thumbnail.thumbnails].url
    result.channel = info.videoDetails.channelId
    
    ngx.say(json:encode(result))
    

    使用

    效果相当好嘛:

    检测每个频道的时间,由之前的十几秒或者几十秒,缩短到了一秒多

  • 相关阅读:
    你真的知道async/await的好处嘛, 并且还会用好呢
    Python基本小程序
    猜数字小程序的实现
    Python第一周基本语句学习整理
    Python环境安装与配置
    作业
    Markdown的学习
    创建一个dynamics CRM workflow (四)
    Dynamics CRM 快速获取custom entity
    Dynamics email的subject标题出现 CRM:0000xxxx
  • 原文地址:https://www.cnblogs.com/chenxuuu/p/11433912.html
Copyright © 2020-2023  润新知