📺 DIY YouTube View Counter: Because Refreshing Your Browser is for Amateurs
Let's be honest: you just uploaded a video, and now you’re refreshing the page every 3 seconds. Your "F5" key is screaming for mercy. It’s time to outsource that obsession to a NodeMCU and a tiny OLED screen.
In this guide, we’re going to build a desktop gadget that stares at the YouTube API so you don't have to.
🛠 The "Ingredients" (Hardware)
NodeMCU (ESP8266): The brains. Cheap, WiFi-enabled, and prone to making you feel like a hacker.
0.96" OLED Display (I2C): 128x64 pixels of pure data-glory.
Jumper Wires: For when you want to feel like you’re defusing a bomb.
A YouTube API Key: Our golden ticket into Google’s data vault.
🔌 The Wiring (Don't Set Anything on Fire)
The OLED uses the I2C protocol, which is fancy talk for "it only needs two data wires." Connect them like this:
| OLED Pin | NodeMCU Pin | Why? |
| VCC | 3.3V | Feed the screen electricity. |
| GND | GND | Completing the circle of life. |
| SCL | D1 | The "Clock" pin (keeps things in sync). |
| SDA | D2 | The "Data" pin (sends the juicy numbers). |
🔑 Step 1: Steal... I mean, Request an API Key
You can't just knock on Google's door and ask for data. You need a key.
Go to the Google Cloud Console.
Create a project (Call it "View-Counter-3000").
Search for "YouTube Data API v3" and click Enable.
Go to Credentials > Create Credentials > API Key.
Keep it secret. If you post it on GitHub, a bot will find it and use up your quota in 4 seconds.
💻 Step 2: The Code
Copy this into your Arduino IDE. You'll need the Adafruit SSD1306 and ArduinoJson (v6+) libraries installed.
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
// --- Configuration ---
const char* ssid = "";
const char* password = "";
const char* apiKey = "";
const char* videoId = "";
// OLED Display Settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Helper function to add commas to strings
String formatWithCommas(String val) {
if (val.length() <= 3) return val;
String res = "";
int cnt = 0;
for (int i = val.length() - 1; i >= 0; i--) {
res = val[i] + res;
cnt++;
if (cnt % 3 == 0 && i != 0) res = "," + res;
}
return res;
}
void setup() {
Serial.begin(115200);
// Initialize OLED (Address 0x3C)
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 10);
display.println("Connecting WiFi...");
display.display();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
display.clearDisplay();
display.setCursor(0, 10);
display.println("WiFi Connected!");
display.display();
delay(1000);
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
fetchYoutubeStats();
}
Serial.println("Waiting 60s...");
delay(60000);
}
void fetchYoutubeStats() {
WiFiClientSecure client;
client.setInsecure();
const char* host = "www.googleapis.com";
if (!client.connect(host, 443)) {
Serial.println("Connection failed!");
return;
}
String url = "/youtube/v3/videos?part=statistics&id=" + String(videoId) + "&key=" + String(apiKey);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"User-Agent: ESP8266\r\n" +
"Accept: application/json\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) return;
}
String jsonResponse = "";
bool isBody = false;
while (client.available()) {
String line = client.readStringUntil('\r');
if (line == "\n" && !isBody) {
isBody = true;
continue;
}
if (isBody) jsonResponse += line;
}
int startIdx = jsonResponse.indexOf('{');
int endIdx = jsonResponse.lastIndexOf('}');
if (startIdx != -1 && endIdx != -1) {
jsonResponse = jsonResponse.substring(startIdx, endIdx + 1);
}
DynamicJsonDocument doc(2048);
DeserializationError error = deserializeJson(doc, jsonResponse);
if (!error && doc.containsKey("items") && doc["items"].size() > 0) {
String rawViews = doc["items"][0]["statistics"]["viewCount"];
String formattedViews = formatWithCommas(rawViews);
// Update Serial
Serial.println("Views: " + formattedViews);
// Update OLED
display.clearDisplay();
// Header
display.setTextSize(1);
display.setCursor(0, 0);
display.println("YouTube Views:");
// Draw horizontal line
display.drawLine(0, 12, 128, 12, WHITE);
// View Count
display.setTextSize(2);
// Center the text roughly based on length
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(formattedViews, 0, 0, &x1, &y1, &w, &h);
display.setCursor((128 - w) / 2, 35);
display.println(formattedViews);
display.display();
} else {
Serial.println("Data fetch failed");
}
}
🧐 How it works (The TL;DR)
The NodeMCU reaches out to Google’s servers, asks for the "statistics" of your video, and gets back a massive blob of text (JSON). Since the ESP8266 is a bit "allergic" to large web pages, we use a regex-style filter to find the { and } brackets, pull out the viewCount, and slap some commas on it so it looks pretty on the screen.
Pro-Tip: If your view count isn't going up, try making better content. (Kidding! Mostly.)
Comments
Post a Comment