api icon indicating copy to clipboard operation
api copied to clipboard

Support for YouTube live streams

Open pajlada opened this issue 3 years ago • 1 comments

Research if we can detect if a YouTube link is a Live Stream, potentially with information about when it goes live, when it went live etc. Given the more volatile nature of live streams, we might want to return a lower cache value for these

pajlada avatar Jan 04 '22 16:01 pajlada

I just noticed this issue existing. I once made a script for GreaseMonkey (Jan 3, 2021), that did exactly that, so I thought I'd share the Infos I have...

I use https://www.googleapis.com/youtube/v3/videos?part=snippet,liveStreamingDetails,contentDetails,localizations,player,statistics,status&key=API_KEY there.

Here https://www.googleapis.com/youtube/v3/videos?part=statistics,snippet,contentDetails,liveStreamingDetails&key=API_KEY would be enough I think.

For the liveStreamingDetails it states the following in the documentation: The `liveStreamingDetails` object contains metadata about a live video broadcast. The object will only be present in a video resource if the video is an upcoming, live, or completed live broadcast. (https://developers.google.com/youtube/v3/docs/videos#liveStreamingDetails)

In my script I used the player API with the InnerTube API-Key, but I think that is probably no option for here as I don't think the API is intended for use outside the Player SDK. Here is a snippet from my code:

let payload = {
  context: {
    client: {
      clientName: 'WEB',
      clientVersion: '2.20210614.06.00',
      originalUrl: window.location.href,
      platform: 'DESKTOP',
      clientFormFactor: 'UNKNOWN_FORM_FACTOR',
      mainAppWebInfo: {
        graftUrl: '/watch?v=' + currentVideoId,
        webDisplayMode: 'WEB_DISPLAY_MODE_BROWSER',
        isWebNativeShareAvailable: false
      }
    },
    user: {
      lockedSafetyMode: false
    },
    request: {
      useSsl: true
    }
  },
  videoId: currentVideoId,
  racyCheckOk: false,
  contentCheckOk: false
};
fetch('https://www.youtube.com/youtubei/v1/player?key=YouTube's own API-Key', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(payload)
}).then(function(response) {
  return response.text();
}).then(function(video_info) {
  try {
    let player_response = JSON.parse(video_info);
    var premiere = !isUndefinedOrNull(player_response) && !player_response.videoDetails.isLiveContent;
    premiere = premiere && !isUndefinedOrNull(data.items[0].liveStreamingDetails);
    var livestream = !isUndefinedOrNull(player_response) && player_response.videoDetails.isLiveContent;
    // ...
  } catch (ex) {
    console.error(ex);
  }
}).catch(error => console.error(error, "\nget_video_info doesn't seem to work"));

If data.items[0].liveStreamingDetails.actualStartTime is not set, I assume, that it is a planned livestream or premiere. If it is set, it is ongoing or ended. Then I check if data.items[0].liveStreamingDetails.actualEndTime is set and if not it is ongoing. Maybe snippet.liveBroadcastContent can help for detecting if it is upcoming, live or something else.

Sadly, I haven't found an option to find out if it is a livestream or premiere without the player API.

Maybe I'll look into the structure myself at some point, but I'd first need to learn Go. I just wanted to leave the infos here already.

Wissididom avatar Mar 30 '23 22:03 Wissididom