如何检查YouTube频道是否直播



我找不到任何信息来检查YouTube频道是否实际上是流媒体。与Twitch你只需要频道名,与API,你可以检查是否有一个直播或不。

我不想使用OAuth,通常一个公共API密钥就足够了。比如查看一个频道的视频,我想知道这个频道是否在播放。

可以使用search.list并指定通道ID,将类型设置为video,将eventType设置为live

例如,当我搜索:

https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UCXswCcAMb5bvEUIDEzXFGYg&type=video&eventType=live&key=[API_KEY]

我得到了以下内容:


{
 "kind": "youtube#searchListResponse",
 "etag": ""sGDdEsjSJ_SnACpEvVQ6MtTzkrI/gE5P_aKHWIIc6YSpRcOE57lf9oE"",
 "pageInfo": {
  "totalResults": 1,
  "resultsPerPage": 5
 },
 "items": [
  {
   "kind": "youtube#searchResult",
   "etag": ""sGDdEsjSJ_SnACpEvVQ6MtTzkrI/H-6Tm7-JewZC0-CW4ALwOiq9wjs"",
   "id": {
    "kind": "youtube#video",
    "videoId": "W4HL6h-ZSws"
   },
   "snippet": {
    "publishedAt": "2015-09-08T11:46:23.000Z",
    "channelId": "UCXswCcAMb5bvEUIDEzXFGYg",
    "title": "Borussia Dortmund vs St. Pauli 1-0 Live Stream",
    "description": "Borussia Dortmund vs St. Pauli Live Stream Friendly Match.",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/W4HL6h-ZSws/default.jpg"
     },
     "medium": {
      "url": "https://i.ytimg.com/vi/W4HL6h-ZSws/mqdefault.jpg"
     },
     "high": {
      "url": "https://i.ytimg.com/vi/W4HL6h-ZSws/hqdefault.jpg"
     }
    },
    "channelTitle": "",
    "liveBroadcastContent": "live"
   }
  }
 ]
}

搜索方法(https://www.googleapis.com/youtube/v3/search)使用起来非常昂贵。默认情况下,您拥有10,000个配额单位,它需要花费100个配额单位(https://developers.google.com/youtube/v3/determine_quota_cost)。这意味着你每天只能收到100个请求,这很糟糕。

可以请求增加配额,但这似乎是暴力强迫的问题。

真的没有其他更简单的方法吗?

伙计们,我找到了更好的方法。是的,它要求您对YouTube页面进行GET请求并解析HTML, 它将与新版本一起工作+征得同意+与captcha一起工作(最有可能,90%)

您所需要做的就是向https://youtube.com/channel/[CHANNELID]/live发出请求并检查<link rel="canonical" />标签的href属性。

例如,

<link rel="canonical" href="https://www.youtube.com/channel/UC4cueEAH9Oq94E1ynBiVJhw">

表示没有直播,而

<link rel="canonical" href="https://www.youtube.com/watch?v=SR9w_ofpqkU">

表示有一个流,你甚至可以通过videoid获取它的数据。

由于规范URL对SEO非常重要,重定向在GETHEAD请求中不再工作,我建议使用我的方法。

下面是我使用的简单脚本:

import { parse } from 'node-html-parser'
import fetch from 'node-fetch'
const channelID = process.argv[2] // process.argv is array of arguments passed in console
const response = await fetch(`https://youtube.com/channel/${channelID}/live`)
const text = await response.text()
const html = parse(text)
const canonicalURLTag = html.querySelector('link[rel=canonical]')
const canonicalURL = canonicalURLTag.getAttribute('href')
const isStreaming = canonicalURL.includes('/watch?v=')
console.log(isStreaming)

然后运行npm init -y && npm i node-html-parser node-fetch在工作目录下创建项目并安装依赖项

然后运行node isStreaming.js UC4cueEAH9Oq94E1ynBiVJhw,它将打印true/false(每次执行400-600毫秒)

它确实需要你依赖于node-html-parsernode-fetch,但你可以用内置的HTTP库(这很糟糕)发出请求,并将其重写为使用正则表达式。(不要用regex解析HTML)

我知道这很老了,但是我自己用PHP解决了这个问题。

$API_KEY = 'your api3 key';
$ChannelID = 'the users channel id';
$channelInfo = 'https://www.googleapis.com/youtube/v3/search?part=snippet&channelId='.$ChannelID.'&type=video&eventType=live&key='.$API_KEY;
$extractInfo = file_get_contents($channelInfo);
$extractInfo = str_replace('},]',"}]",$extractInfo);
$showInfo = json_decode($extractInfo, true);
if($showInfo['pageInfo']['totalResults'] === 0){
    
    echo 'Users channel is Offline';
    
} else {
    echo 'Users channel is LIVE!';
}

我也在与API限制作斗争。我发现最可靠和最便宜的方法是简单地将HEAD请求到https://www.youtube.com/channel/CHANNEL_ID/live。如果频道是直播的,那么它将自动加载流。如果没有,那么它将加载频道视频馈送。您可以简单地检查Content-Length报头大小来确定哪个。

根据你所在的地区,你可能需要接受cookie同意页面。只需发送您的请求与cookies={ "CONSENT": "YES+cb.20210420-15-p1.en-GB+FX+634" } .

如果你指向streamlink在https://www.youtube.com/channel/CHANNEL_ID/live链接,它会告诉你是否直播

  • 。Lofi节拍通常是现场的,

    $ streamlink "https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow/live"
    [cli][info] Found matching plugin youtube for URL https://www.youtube.com/channel/UCSJ4gkVC6NrvII8umztf0Ow/live
    Available streams: 144p (worst), 240p, 360p, 480p, 720p, 1080p (best)
    
  • 而MKBHD不是

    $ streamlink "https://www.youtube.com/c/mkbhd/live"          
    [cli][info] Found matching plugin youtube for URL https://www.youtube.com/c/mkbhd/live
    error: Could not find a video on this page
    

我找到的最简单的方法就是抓取站点。这可以通过查找以下内容来实现:<link rel="canonical" href="linkToActualYTLiveVideoPage">正如Vitya的回答。

这是我使用bs4的简单Python代码:
import requests
from bs4 import BeautifulSoup
def is_liveYT():
    channel_url = "https://www.youtube.com/c/LofiGirl/live"
    page = requests.get(channel_url, cookies={'CONSENT': 'YES+42'})
    soup = BeautifulSoup(page.content, "html.parser")
    live = soup.find("link", {"rel": "canonical"})
    if live: 
        print("Streaming")
    else:
        print("Not Streaming")
if __name__ == "__main__":
    is_liveYT()
这很奇怪,老实说,YouTube没有一个简单的方法通过API来做到这一点,尽管这可能更容易。

我发现@VityaSchel的答案非常有用,但它不区分有直播计划的频道和那些正在直播的频道

为了区分预定和直播,我扩展了他的代码来访问YouTube Data API以查找直播细节:

import { parse } from 'node-html-parser'
import fetch from 'node-fetch'
const youtubeAPIkey = 'YOUR_YOUTUBE_API_KEY'
const youtubeURLbase = 'https://www.googleapis.com/youtube/v3/videos?key=' + youtubeAPIkey + '&part=liveStreamingDetails,snippet&id='
const c = {cid: process.argv[2]}    // process.argv is array of arguments passed in console
const response = await fetch(`https://youtube.com/channel/${c.cid}/live`)
const text = await response.text()
const html = parse(text)
const canonicalURLTag = html.querySelector('link[rel=canonical]')
const canonicalURL = canonicalURLTag.getAttribute('href')
c.live = false
c.configured = canonicalURL.includes('/watch?v=')
if (!c.configured) process.exit()
c.vid = canonicalURL.match(/(?<==).*/)[0]
const data = await fetch(youtubeURLbase + c.vid).then(response => response.json())
if (data.error) {
    console.error(data)
    process.exit(1)
}
const i = data.items.pop()  // pop() grabs the last item
c.title = i.snippet.title
c.thumbnail = i.snippet.thumbnails.standard.url
c.scheduledStartTime = i.liveStreamingDetails.scheduledStartTime
c.live = i.liveStreamingDetails.hasOwnProperty('actualStartTime')
if (c.live) {
    c.actualStartTime = i.liveStreamingDetails.actualStartTime
}
console.log(c)

上面的输出示例:

% node index.js UCNlfGuzOAKM1sycPuM_QTHg
{
  cid: 'UCNlfGuzOAKM1sycPuM_QTHg',
  live: true,
  configured: true,
  vid: '8yRgYiNH39E',
  title: '🔴 Deep Focus 24/7 - Ambient Music For Studying, Concentration, Work And Meditation',
  thumbnail: 'https://i.ytimg.com/vi/8yRgYiNH39E/sddefault_live.jpg',
  scheduledStartTime: '2022-05-23T01:25:00Z',
  actualStartTime: '2022-05-23T01:30:22Z'
}

每个YouTube频道作为永久直播,即使该频道目前没有积极直播。在liveStream资源中,您可以找到一个名为isDefaultStream的布尔值。

但是我们从哪里可以得到这个视频(直播)id?转到https://www.youtube.com/user/CHANNEL_ID/live,右键点击流,复制视频URL。

您现在可以向https://youtube.googleapis.com/youtube/v3/videos?part=liveStreamingDetails&id=[VIDEO_ID]&key=[API_KEY](该请求的配额成本为1个单位,见这里)

如果流当前是活动的/在线的,这将是结果。

{
    "kind": "",
    "etag": "",
    "items": [
        {
            "kind": "",
            "etag": "",
            "id": "",
            "liveStreamingDetails": {
                "actualStartTime": "",
                "scheduledStartTime": "",
                "concurrentViewers": "",
                "activeLiveChatId": ""
            }
        }
    ],
    "pageInfo": {
        "totalResults": 1,
        "resultsPerPage": 1
    }
}

如果流当前处于离线状态,则属性concurrentViewers不存在。换句话说,在线和离线直播之间的唯一区别是concurrentViewers是否存在。有了这些信息,您就可以检查频道当前是否正在流式传输(至少对于它的默认流式传输)。

考虑到搜索操作的成本,我发现youtube API非常受限。使用aiohttp和beautifulsoup抓取网页不是一个选择,因为更好的指示器需要javascript支持。因此,我转向。我寻找css选择器

#info-text然后搜索字符串Started streaming或其中包含watching now

你也可以用flask在heroku上运行一个小API。

这是另一个不使用YouTube Data API的解决方案。如果你解析出这些元标签,它们会告诉你这是否是一个直播以及开始时间。如果缺少这些标签,则表示频道不是活动的。

也有额外的元标签,列出标题,描述和其他有用的信息。

要查看它是否是一个计划流,只需检查startDate并将其与当前时间进行比较。

<span itemprop="publication" itemscope itemtype="http://schema.org/BroadcastEvent">
   <meta itemprop="isLiveBroadcast" content="True">
   <meta itemprop="startDate" content="2022-07-13T21:47:38+00:00">
</span>

您可以通过以下方式查询这些标签:

document.querySelector('meta[itemprop="isLiveBroadcast"]').content === "True"
旁注:您甚至不需要解析HTML就可以知道,因为如果频道不是活动的,标记将根本不存在,所以这里有一个快速而肮脏的解决方案:
const data = await fetch(`https://www.youtube.com/[id]/live`)
const isLive = (await data.text()).includes('isLiveBroadcast')

相关内容

  • 没有找到相关文章