How to check if YouTube channel is streaming live
Asked Answered
T

11

32

I can't find any informations to check if a YouTube channel is actually streaming or not. With Twitch you just need the channel name, and with the API you can check if there is a live or not.

I don't want to use OAuth, normally a public API key is enough. Like checking the videos of a channel I want to know if the channel is streaming.

Tripura answered 8/9, 2015 at 9:36 Comment(1)
Related: #44616204Haddock
E
39

You can do this by using search.list and specifying the channel ID, setting the type to video, and setting eventType to live.

For example, when I searched for:

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

I got the following:


{
 "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"
   }
  }
 ]
}
Eventuality answered 8/9, 2015 at 16:54 Comment(8)
but can we have the id of the video steam ?Tripura
You can find the ID if you look at the items resource -> id -> videoId. In the example I posted above, the ID of the video stream is W4HL6h-ZSws.Eventuality
No problem, happy to help.Eventuality
But this API actually responds only after few minutes after we start the live stream, it doesn't show any data when the stream has just started. @Eventuality could you please suggest an alternative.Gherkin
This also returns videos that are "live" but aren't actually streaming, is there any way to filter those guys out?Alexandrina
Any update on this, the last two comments are still issues for me.Wendeline
Keep in mind that call to this api costs you 100 quota, which means you can only do 100 requests per day.Chlorine
In Ruby, use yt gem and do Yt::Channel.new(id: ...).videos.where(event_type: 'live')Blayze
S
13

The search-method (https://www.googleapis.com/youtube/v3/search) is awfully expensive to use though. It costs 100 quota units (https://developers.google.com/youtube/v3/determine_quota_cost) out of the 10,000 you have by default. This means you only get 100 requests per day which is terrible.

You could request an increase in the quota but that seems like brute forcing the the problem.

Is there really no other simpler method?

Spermophyte answered 2/4, 2019 at 17:18 Comment(3)
Welcome to SO. This post doesn't really answer the question. When you get more reputation, you'll be able to post this sort of material as comments...Zoller
this is exactly my battle right now in 2019... hard to imagine youtube doesn't provide a cheap API request just to see if a channel is live... using the liveBroadcast API doesn't help because it's not comprehensive to me and there is no way to specify a channel...Relume
May help: #56386032Warenne
C
13

Guys I found better way to do this. Yes, it requires you to make GET requests to a YouTube page and parse HTML, but it will work with newer versions + works with consent + works with captcha (most likely, 90%)

All you need to do is make a request to https://youtube.com/channel/[CHANNELID]/live and check the href attribute of the <link rel="canonical" /> tag.

For example,

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

means there is no livestream, while

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

means there is a stream, and you can even fetch its data by videoid.

Since canonical URL is very important for SEO and redirect does not work in GET or HEAD requests anymore, I recommend using my method.

Also here is the simple script I use:

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)

Then run npm init -y && npm i node-html-parser node-fetch to create project in working directory and install dependencies

Then run node isStreaming.js UC4cueEAH9Oq94E1ynBiVJhw and it will print true/false (400-600 ms per one execution)

It does require you to depend on node-html-parser and node-fetch, but you can make requests with the built-in HTTP library (which sucks) and rewrite this to use regex. (Do not parse HTML with regex.)

Chlorine answered 18/11, 2021 at 20:33 Comment(2)
Backlinked from another answer.Ehtelehud
Thank you. Great answer. Not using the Google API is generally preferred, as it forces a lot of artifical limitations & weirdness, whereas parsing a HTML page at least gives you the "real result" you are looking for....Harpy
C
10

I know this is old, but I figured it out myself with 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!';

}
Cologarithm answered 29/7, 2016 at 3:2 Comment(1)
There is a more-complete, official code sample for listing live streams: github.com/youtube/api-samples/blob/master/php/list_streams.phpHaddock
G
5

I was also struggling with API limits. The most reliable and cheapest way I've found was simply a HEAD request to https://www.youtube.com/channel/CHANNEL_ID/live. If the channel is live then it will auto load the stream. If not then it will load the channels videos feed. You can simply check the Content-Length header size to determine which. If live the size is almost 2x when NOT live.

And depending on your region you might need to accept the cookies consent page. Just send your request with cookies={ "CONSENT": "YES+cb.20210420-15-p1.en-GB+FX+634" }.

Gallard answered 23/4, 2021 at 20:2 Comment(0)
S
3

if you point streamlink at a https://www.youtube.com/channel/CHANNEL_ID/live link, it will tell you if it is live or not

  • e.g. lofi beats is usually live,

    $ 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)
    
  • whereas MKBHD is not

    $ 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
    
Subhuman answered 16/2, 2021 at 16:43 Comment(0)
S
3

The easisest way that I have found to this has been scraping the site. This can be done by finding this: <link rel="canonical" href="linkToActualYTLiveVideoPage"> as in Vitya's answer.

This is my simple Python code using bs4:

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()

It is pretty weird, honestly, that YouTube doesn't have a simple way to do this through the API, although this is probably easier.

Syzran answered 23/2, 2022 at 17:41 Comment(0)
W
1

Every YouTube channel as a permanent livestream, even if the channel is currently not actively livestreaming. In the liveStream resource, you can find a boolean named isDefaultStream.

But where can we get this video (livestream) id? Go to https://www.youtube.com/user/CHANNEL_ID/live, right click on the stream and copy the video URL.

You can now make a GET request to https://youtube.googleapis.com/youtube/v3/videos?part=liveStreamingDetails&id=[VIDEO_ID]&key=[API_KEY] (this request has a quota cost of 1 unit, see here)

This will be the result if the stream is currently active/online.

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

If the stream is currently offline, the property concurrentViewers will not exist. In other words, the only difference between an online and offline livestream is that concurrentViewers is present or not present. With this information, you can check, if the channel is currently streaming or not (at least for his default stream).

Wayward answered 12/3, 2022 at 22:27 Comment(0)
W
1

I found the answer by @VityaSchel to be quite useful, but it doesn't distinguish between channels which have a live broadcast scheduled, and those which are broadcasting live now.

To distinguish between scheduled and live, I have extended his code to access the YouTube Data API to find the live streaming details:

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)

Sample output from the above:

% 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'
}
Women answered 23/5, 2022 at 5:39 Comment(1)
Can the same be achieved without using the official API?Harpy
P
0

I found youtube API to be very restrictive given the cost of search operation. Web scraping with aiohttp and beautifulsoup was not an option since the better indicators required javascript support. Hence I turned to selenium. I looked for the css selector

#info-text and then search for the string Started streaming or with watching now in it.

You can run a small API on heroku with flask as well.

Parsimonious answered 8/4, 2021 at 9:16 Comment(0)
C
0

Here is another solution without usage of the YouTube Data API. If you parse out these meta tags they tell you if it is a live broadcast along with the start time. If these tags are missing, then the channel is not live.

There are also additional meta tags available that list out the title, description and other useful information.

To view whether it is a scheduled stream, just check the startDate and compare it to the current time.

<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>

You can query for these tags by:

document.querySelector('meta[itemprop="isLiveBroadcast"]').content === "True"

Sidenote: You don't even need to parse the HTML to know, since the tag won't exist at all if the channel isn't live, so here's a quick and dirty solution:

const data = await fetch(`https://www.youtube.com/[id]/live`)
const isLive = (await data.text()).includes('isLiveBroadcast')
Catchpenny answered 5/3, 2023 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.