Never miss your favourite YouTube channel going live again with this Particle Photon-based indicator.
I'm a big fan of the scanlime-in-progress live streams Micah Elizabeth Scott (Scanlime) does under the watchful eye of Tuco the cat. Micah's streams are often epic, building, hacking and tinkering with everything from reverse engineering firmware to building a Tuco flyer which I find really interesting, sometimes these are adhoc and I found I frequently missed the first few hours until I noticed the email from YouTube (once I remembered to enable notifications).
To solve this problem I put the Particle WebHook to use to query the YouTube API, I added a few LEDs on a ThingyStick prototype PCB to indicate the channel being live. I had planned to 3D print a nice lime enclosure but that's still pending, the final indication can be modified, maybe a big LED, or a "Live" sign using a relay, or maybe some nice RGB Neopixels, the choice is yours.
Before getting started we need to know the channel id that we are interested in, this can be found from the YouTube channel page URL. e.g. Scanlime-in-progress Is UC8G48_G7suQlScUudVXyGkg
Next you'll need an api key for YouTube Data API V3 and to enable the Api for your account. Follow the instructions on the YouTube Data Api Overview. You need a google account, enable the YouTube API and on the credential page to create an API Key.
At the time of development Google didn't have a specific API to tell if a channel was live, instead we needed search with filters for channelId and live status, this consumes a quota of 100 units per search, compared to a single unit for a channel list, so it's expensive to do. We are given a quota of 1, 000, 000 free units per month, which equates to 10, 000 searches per month (i.e. 322 per day, 13 per hour, or one every 5 minutes) before we start to get billed for using the query.
WebhookWe use a Particle webhook to query the YouTube API. Add a new integration through the Particle Console Integration tab and select Webhook.
We need to use advanced parameters so be sure to open the Advanced Settings section and enter the parameters as:
EventName: scanlimelive
Url: https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=<ChannelId>&type=video&eventType=live&key=<Google YouTube Api Key>
Request Type: Get
Request Format: Query Parameters
Device: Any
Response Topic: youtubelive
Error Response Topic: youtubeliveerror
Response Template: {{pageInfo.totalResults}}
The resulting json should look something like this.
{
"event": "scanlimelive",
"responseTopic": "youtubelive",
"errorResponseTopic": "youtubeliveerror",
"url": "https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UC8G48_G7suQlScUudVXyGkg&type=video&eventType=live&key=<Insert your Google YouTube Key Here>",
"requestType": "GET",
"noDefaults": true,
"rejectUnauthorized": true,
"responseTemplate": "{{pageInfo.totalResults}}"
}
This webhook is specific to scanlime-in-progress channel. With this setup, we can then get our Photon to publish an event ("scanlimelive") that triggers this webhook, once the API responds the result is published to the response topic (this will actually be ""youtubelive/0" not just "youtubelive" as suggested in the webhook setup, which our Photon is subscribed to.
Hardware IndicatorMy original plan was to 3D print a lime, but as yet I've not managed this, so the indicator for now is just some LEDs, but it works just we well. I've ended up with 6 LEDs on a Wide Photon ThingySticks prototype PCB (Full disclosure: I developed and sell these prototype PCBs on Tindie, you may prefer to use a different board, the Particle Relay shield for example).
I fitted the PCB with 6 individually addressable LEDs (D2-D7), these are all used for scanlime-in-progress, each one could be used for a different channel, however the limitations from the Google API search quota usage makes this difficult (or rather, expensive!).
This PCBs can be powered by plugging the USB A plug directly to a USB outlet allowing some simple mounting options.
You could use any indicator you like, perhaps the Particle Relay shield to power a larger indicator, or a big red "Live" light.
Schematic:The electronics is very simple, power in, and 6 LEDs. I've used 1206 LEDs to fit on the ThingyStick, power comes either from the Photons USB B socket, or the ThingySticks USB A Plug (or optionally the JST battery connector on the underside of the board).
The full firmware is in the attachments section, here we'll just look at the interesting parts here.
In setup we subscribe to the webhook response topic, and take control of the onboard RGB LED.
void setup() {
...
// subscribe to the response topic to get notified when the query responds.
Particle.subscribe("youtubelive/0", youTubeLiveHandler, MY_DEVICES);
...
// Take control of the Photon's RGB LED to use this as
// a basic indicator as well as the external LEDs.
RGB.control(true);
// Blue - don't know - no response.
RGB.color(0, 0, 255);
}
In loop we essentially sleep, waking once per minute to publish the "scanlimelive" event, this triggers our webhook and hence the YouTube data query. The delay here needs to be much longer to prevent going over the quota usage.
void loop() {
// Request Webhook query YouTube API for Scanlime channel.
Particle.publish("scanlimelive");
// give it n seconds before we try and check again.
delay(60000);
}
Next we need the subscription handler. Our response template returns only the number of results found from the search, this is perfect as it will be either 1 if the channel is live, or 0.
void youTubeLiveHandler(const char *event, const char *data) {
// "responseTemplate": "{{pageInfo.totalResults}}"
// data contains the number of results
int resultCount = atoi(data);
// Set
setLEDs(resultCount > 0);
// Publish a status message so this can also
// be picked up by Tinamous or another platform (e.g. IFTTT)
if (resultCount > 0) {
if (!isLive) {
Particle.publish("status", "Scanlime live stream started. count: " + String(resultCount));
}
isLive = true;
} else {
// Handle the channel no longer being live.
if (isLive) {
Particle.publish("status", "Scanlime not live!");
}
isLive = false; // :-(
}
}
void setLEDs(bool state) {
// LEDs are active low.
digitalWrite(D2, !state);
digitalWrite(D3, !state);
digitalWrite(D4, !state);
digitalWrite(D5, !state);
digitalWrite(D6, !state);
digitalWrite(D7, !state);
// If live, set the onboard RGB LED to Lime color.
if (state) {
RGB.color(50, 205, 50); // Lime Green
} else {
RGB.color(0, 0, 0);
}
}
And that's it. Plug in, wait for the LEDs to light up, then tune in for an epic Scanlime In Progress live stream featuring Tuco.
Comments