Ютуб статистика на esp32

Тема в разделе "Глядите, что я сделал", создана пользователем issaom, 8 окт 2020.

  1. issaom

    issaom Гуру

    На всякий случай сюда положу - мало кому захочется сделать полноценный мониторинг Ютуб канала
    Picture 63.jpg

    Picture 60.jpg
    Отображение количества просмотров, лайков, дизлайков, коментариев:
    • за текущие 5 минут (M+)
    • за предыдущие 5 минут (M-)
    • за текущий час (H+)
    • за предыдущий час (H-)
    • за текущие сутки (D+)
    • за предыдущие сутки (D-)
    • счетчик подписчиков
    • количество видео на канале
    • световая индикация в случае появления нового комментария (максимальное время обновления 5 минут)
    • возможность отключение дисплея
    • сенсорный интерфейс
    • возможность отключения питания (сохранение данных за час и сутки)
    ютуб схема.JPG
    Код разбит на отдельные разделы. Все написано в среде Arduino IDE

    Код (C++):
    #define RedL 17
    #define GreL 16
    #define BluL 2

    #include <WiFi.h>
    #include <HTTPClient.h>
    #include "time.h"
    #include <SPI.h>
    #include <U8g2lib.h>
    #include <EEPROM.h>
    U8G2_SSD1309_128X64_NONAME0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 5, /* dc=*/ 4, /* reset=*/ 15);

    const char* ssid     = "";             // ssid
    const char* password = "";            // пароль
    const char* ntpServer = "pool.ntp.org";       // сервер времени
    const long  gmtOffset_sec = 10800;            // 3600*3=10800 (UTC+3) Москва
    const int   daylightOffset_sec = 0;           // переход на летнее время
    String youtubeApiKey = "";

    String youtubeNameChammel = "UCWnYJoytogNmXg4BHZV8XLg";

    String   AllVideoList = "";                     // Список всех видео на канале
    uint32_t AllVideoCount = 0;                // Количество видео на канале

    // Переменные для отображения полученной статистики
    uint32_t ShowwC = 0;                        // Количество просмотров
    uint32_t ShowlC = 0;                          // Количество лайков
    uint32_t ShowdC = 0;                          // Количество дизлайков
    uint32_t ShowcC = 0;                          // Количество комментариев

    uint32_t OldShowcC = 0;                    // Переменная для проверки изменения количества комментариев

    uint32_t ShowsC = 0;                          // Количество подписчиков
    uint32_t ShowvC = 0;                          // Количество видео для обработки

    // Агрегатные переменные
    uint32_t wC = 0;                              // Количество просмотров
    uint32_t lC = 0;                              // Количество лайков        2,3
    uint32_t dC = 0;                              // Количество дизлайков     4,6
    uint32_t cC = 0;                              // Количество комментариев  6,7

    // Переменные для отображения разницы между текущим и предыдущим
    int32_t DwC = 0;                              // Дельта Количество просмотров     [1] - [0]
    int32_t DlC = 0;                              // Дельта Количество лайков         [3] - [2]
    int32_t DdC = 0;                              // Дельта Количество дизлайков      [5] - [4]
    int32_t DcC = 0;                              // Дельта Количество комментариев   [7] - [6]

    uint32_t Last5Min [] = {0, 0, 0, 0, 0, 0 , 0, 0}; // Статистика за последние 5 минут

    uint32_t Last1Hour [] = {0, 0, 0, 0, 0, 0, 0, 0};
    int Last1HourADDR = 0;                            // Адрес хранения массива во флеше
    uint8_t *Last1HourPTR  = (uint8_t*)&Last1Hour;    // Указатель на массив Last1Hour

    uint32_t Last1Day [] = {0, 0, 0, 0, 0, 0, 0, 0};
    int Last1DayADDR = 32;                            // Адрес хранения массива во флеше
    uint8_t *Last1DayPTR  = (uint8_t*)&Last1Day;      // Указатель на массив Last1Day

    boolean wifiOK = false;
    void wifiShow () {
      u8g2.setFont(u8g2_font_open_iconic_all_1x_t);
      if (wifiOK) {
        u8g2.setCursor(119, 9); u8g2.write(253);        // wifi OK
      } else {
        u8g2.setCursor(119, 9); u8g2.write(121);        // wifi no OK
      }
    }

    boolean refreshOK = false;
    void refreshShow () {
      u8g2.setFont(u8g2_font_open_iconic_all_1x_t);
      if (refreshOK) {
        u8g2.setCursor(119, 20); u8g2.write(243);       // идет обновление данных
      } else {
        u8g2.setCursor(119, 20); u8g2.write(115);       // обновление данных закончено
      }
    }

    TaskHandle_t Task1;
    TaskHandle_t Task2;
    #include "ESP32_Task1code.h"
    #include "ESP32_Task2code.h"

    void setup() {
      Serial.begin(115200);
      EEPROM.begin(64);
      pinMode (RedL, OUTPUT);
      pinMode (GreL, OUTPUT);
      pinMode (BluL, OUTPUT);

      u8g2.begin();
      u8g2.setFont(u8g2_font_profont12_mr);           // Устанавливаем шрифт (высота 8 пикселей)
      u8g2.clearBuffer();                             // очищаем память дисплея и картинку
      u8g2.sendBuffer();                              // обновляем дисплей
      u8g2.setCursor(0, 8);
      u8g2.print(ssid);
      wifiShow ();
      u8g2.setFont(u8g2_font_profont12_mr);
      u8g2.sendBuffer();
      u8g2.setCursor(0, 19);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        u8g2.print(".");
        u8g2.sendBuffer();
      }
      u8g2.clearBuffer();
      u8g2.setCursor(0, 8);
      u8g2.print(WiFi.localIP());                     // Печатаем IP - шник
      wifiOK = true;
      wifiShow ();
      u8g2.sendBuffer();
      delay(5000);

      //восстанавливаем данные за час и сутки если было отключение питания
      for (byte i = 0; i < 32; i++) {
        *(Last1HourPTR + i) = EEPROM.read(Last1HourADDR + i);
      }
      for (byte i = 0; i < 32; i++) {
        *(Last1DayPTR + i) = EEPROM.read(Last1DayADDR + i);
      }

      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);  // Синхронизируем внутренние часы с временем из интернета
      //delay(2000);
      xTaskCreatePinnedToCore(Task1code, "Task1", 10000, NULL, 1, &Task1, 0); //ядро 0
      delay(500);
      xTaskCreatePinnedToCore(Task2code, "Task2", 10000, NULL, 1, &Task2, 1); //ядро 1
      delay(500);
    }

    void loop() {

    }
     
    Последнее редактирование: 8 окт 2020
    OldKryptos, Daniil и NikitOS нравится это.
  2. issaom

    issaom Гуру

    ESP32_Task1code.h

    Код (C++):
    // Ядро 0 отображаем часы, данные на дисплее, опрашиваем сенсорные кнопки
    #include "ESP32_fourBtSens.h"

    uint8_t ShowDisp = 0; // Переменная для обновления дисплея 0.5 сек

    boolean dot = false;                                                      // Точки на часах
    const uint8_t Yico[]  = {0x00, 0x7E, 0xF7, 0xE7, 0xC7, 0xE7, 0xF7, 0x7E}; // Иконка Ютуба

    uint8_t sectionI = 0;                                                     // Секция отображения
    const char *sectionS[]  = {                                               // Массив секции для отображения
      "M+",     // 0 статистика за 5 минут
      "M-",     // 1 статистика за 1 час
      "H+",     // 2 статистика за 1 день
      "H-",     // 0 статистика за 5 минут
      "D+",     // 1 статистика за 1 час
      "D-",     // 2 статистика за 1 день
    };

    boolean powerSave = false;                                        // Отображаем / спим
    uint8_t BtSt1and3 = 0;                                            // Фильтр для 2-х нажатых кнопок

    // Распечатываем страничку с Ютубе Аналитикой (общие параметры)
    void printYoutubeA() {

      struct tm timeinfo;                          // получаем дату и время
      if (!getLocalTime(&timeinfo)) {
        Serial.println("Failed to obtain time");
        return;
      }

      if (sectionI == 0) {
        // рассчитываем дельту для странички за последние 5 минут (M+)
        DwC = ShowwC - Last5Min [1];              // Дельта Количество просмотров
        DlC = ShowlC - Last5Min [3];              // Дельта Количество лайков
        DdC = ShowdC - Last5Min [5];              // Дельта Количество дизлайков
        DcC = ShowcC - Last5Min [7];              // Дельта Количество комментариев
      }

      if (sectionI == 1) {
        // рассчитываем дельту для странички за предудущие за последними 5 минут (M-)
        DwC = Last5Min [1] - Last5Min [0];        // Дельта Количество просмотров
        DlC = Last5Min [3] - Last5Min [2];        // Дельта Количество лайков
        DdC = Last5Min [5] - Last5Min [4];        // Дельта Количество дизлайков
        DcC = Last5Min [7] - Last5Min [6];        // Дельта Количество комментариев  
      }

      if (sectionI == 2) {
        // рассчитываем дельту для странички за текущий час (H+)
        DwC = ShowwC - Last1Hour [1];              // Дельта Количество просмотров
        DlC = ShowlC - Last1Hour [3];              // Дельта Количество лайков
        DdC = ShowdC - Last1Hour [5];              // Дельта Количество дизлайков
        DcC = ShowcC - Last1Hour [7];              // Дельта Количество комментариев
      }

      if (sectionI == 3) {
        // рассчитываем дельту для странички за предыдущий час (H-)
        DwC = Last1Hour [1] - Last1Hour [0];        // Дельта Количество просмотров
        DlC = Last1Hour [3] - Last1Hour [2];        // Дельта Количество лайков
        DdC = Last1Hour [5] - Last1Hour [4];        // Дельта Количество дизлайков
        DcC = Last1Hour [7] - Last1Hour [6];        // Дельта Количество комментариев
      }

      if (sectionI == 4) {
        // рассчитываем дельту для странички за текущие сутки (D+)
        DwC = ShowwC - Last1Day [1];              // Дельта Количество просмотров
        DlC = ShowlC - Last1Day [3];              // Дельта Количество лайков
        DdC = ShowdC - Last1Day [5];              // Дельта Количество дизлайков
        DcC = ShowcC - Last1Day [7];              // Дельта Количество комментариев
      }

      if (sectionI == 5) {
        // рассчитываем дельту для странички за предудущие сутки (D-)
        DwC = Last1Day [1] - Last1Day [0];        // Дельта Количество просмотров
        DlC = Last1Day [3] - Last1Day [2];        // Дельта Количество лайков
        DdC = Last1Day [5] - Last1Day [4];        // Дельта Количество дизлайков
        DcC = Last1Day [7] - Last1Day [6];        // Дельта Количество комментариев
      }


      u8g2.clearBuffer();                            // очищаем экран
      wifiShow ();                                   // отображаем статус Wi Fi
      refreshShow ();                                // отображаем процесс обновления данных
      u8g2.setFont(u8g2_font_open_iconic_human_1x_t);
      u8g2.setCursor(0,  8); u8g2.print(char(64));   // ico просмотры
      u8g2.setCursor(0, 52); u8g2.print(char(68));   // ico подписчики
      u8g2.setFont(u8g2_font_open_iconic_www_1x_t);
      u8g2.setCursor(0, 19); u8g2.print("I");        // ico дайки
      u8g2.setCursor(0, 30); u8g2.print("R");        // ico дизлайки
      u8g2.setCursor(0, 41); u8g2.print("K");        // ico комментарии
      u8g2.drawXBMP(0, 56, 8, 8, Yico);              // ico Ютуба

      u8g2.setFont(u8g2_font_profont12_mr);
      u8g2.setCursor(12,  8); u8g2.print(ShowwC);   // Количество просмотров
      u8g2.print(" +"); u8g2.print(DwC);

      u8g2.setCursor(12, 19); u8g2.print(ShowlC);   // Количество лайков
      u8g2.print(" +"); u8g2.print(DlC);

      u8g2.setCursor(12, 30); u8g2.print(ShowdC);   // Количество дизлайков
      u8g2.print(" +"); u8g2.print(DdC);

      u8g2.setCursor(12, 41); u8g2.print(ShowcC);   // Количество комментариев
      u8g2.print(" +"); u8g2.print(DcC);

      u8g2.setCursor(12, 52); u8g2.print(ShowsC);   // Количество подписчиков

      u8g2.setCursor(12, 64); u8g2.print(ShowvC);   // Количество видео в файле

      u8g2.setCursor(45, 64);                       // Распечатываем дату и время
      u8g2.print(&timeinfo, "%H");
      if (dot) u8g2.print(':'); else u8g2.print(' ');
      dot = !dot;
      u8g2.print(&timeinfo, "%M");
      //u8g2.print(':');
      //u8g2.print(&timeinfo, "%S");
      u8g2.print(' ');
      u8g2.print(&timeinfo, "%d");
      u8g2.print('.');
      u8g2.print(&timeinfo, "%m");
      //u8g2.print('.');
      //u8g2.print(&timeinfo, "%Y");
      u8g2.print(" ");
      u8g2.print(sectionS[sectionI]);
      u8g2.sendBuffer();                              // отображаем содержимое экрана
    }

    void Task1code( void * pvParameters ) {

      for (;;) { //бесконечный цикл

        readBtSens ();                                // обновляем переменную StBt
        if (bitRead(StBt, 0) && !bitRead(StBt, 1)) {  // Обрабатываем только одно прикосновение 1-я кнопка
          bitSet(StBt, 1);                            // пока не отпустят кнопку - больше не реагируем
          if (sectionI != 5) sectionI++;              // меню листать вперед
        }
        if (bitRead(StBt, 2) && !bitRead(StBt, 3)) {  // Обрабатываем только одно прикосновение 2-я кнопка
          bitSet(StBt, 3);                            // пока не отпустят кнопку - больше не реагируем
          digitalWrite(BluL,LOW);                     // Гасим светодиод комментариев
        }
        if (bitRead(StBt, 4) && !bitRead(StBt, 5)) {  // Обрабатываем только одно прикосновение 3-я кнопка
          bitSet(StBt, 5);                            // пока не отпустят кнопку - больше не реагируем
          if (sectionI != 0) sectionI--;              // меню листать назад
        }
        if (bitRead(StBt, 6) && !bitRead(StBt, 7)) {  // Обрабатываем только одно прикосновение 4-я кнопка
          bitSet(StBt, 7);                            // пока не отпустят кнопку - больше не реагируем
          // заначка
        }

        if ((StBt == B00110011) && (BtSt1and3 == 0 )) {   // Нажаты 1 и 3 кнопка одновременно вкл/выкл дисплея
          powerSave = !powerSave;
          u8g2.setPowerSave(powerSave);
          BtSt1and3 = 100;                                 // Не реагируем 1 секунду
        } else {
          if (BtSt1and3 != 0) BtSt1and3--;
        }

        delay(10);

        ShowDisp ++;                                     // Обновляем содержимое дисплея 1 раз в 0.5 сек
        if (ShowDisp >= 50) {
          printYoutubeA();
          ShowDisp = 0;
        }
      }
    }
     
     
    NikitOS нравится это.
  3. issaom

    issaom Гуру

    ESP32_Task2code.h

    Код (C++):
    String httpGETRequest(const char* serverName) {
      HTTPClient http;
      // Your IP address with path or Domain name with URL path
      http.begin(serverName);
      // Send HTTP POST request
      int httpResponseCode = http.GET();
      String payload = "{}";
      if (httpResponseCode > 0) {
        //Serial.print("HTTP Response code: ");
        //Serial.println(httpResponseCode);
        payload = http.getString();
      }
      else {
        //Serial.print("Error code: ");
        //Serial.println(httpResponseCode);
      }
      // Free resources
      http.end();
      return payload;
    }

    #include "ESP32_youtubeA.h"               // набор функций для сбора статистики Ютуба
    // таймер 1 минута
    int Now1Min = 0;
    int Old1Min = 0;
    // таймер 5 минут
    int Old5Min = 0;
    // таймер 10 минут
    int Old10Min = 0;
    // таймер 1 час
    int Now1Hour = 0;
    int Old1Hour = 0;
    // таймер 1 день
    int Now1Day = 0;
    int Old1Day = 0;


    void Task2code( void * pvParameters ) {

      refreshOK = true;

      getYoutubeChanel();           // Получаем количество подписчиков
      makeVideoList();              // Создаем лист с ID видео на канале
      refreshA ();                  // Обновляем статистику
      ShowwC = wC;                  // Количество просмотров - отдаем для отображения
      ShowlC = lC;                  // Количество лайков - отдаем для отображения
      ShowdC = dC;                  // Количество дизлайков - отдаем для отображения
      ShowcC = cC;                  // Количество комментариев - отдаем для отображения
      // зануляем 5 минутную статистику (данные будут доступны через 5+5 минут)
      Last5Min [1] = ShowwC;
      Last5Min [3] = ShowlC;
      Last5Min [5] = ShowdC;
      Last5Min [7] = ShowcC;
      Last5Min [0] = ShowwC;
      Last5Min [2] = ShowlC;
      Last5Min [4] = ShowdC;
      Last5Min [6] = ShowcC;


      struct tm timeinfo;                                    // получаем дату и время
      if (!getLocalTime(&timeinfo)) {
        Serial.println("Failed to obtain time");
        return;
      }
      // все события не должны произойти при первом включении
      Now1Min = timeinfo.tm_min;
      Old1Min = Now1Min;
      Now1Hour = timeinfo.tm_hour;
      Old1Hour = Now1Hour;
      Now1Day =  timeinfo.tm_mday;
      Old1Day = Now1Day;

      refreshOK = false;

      for (;;) { //бесконечный цикл

        struct tm timeinfo;                                  // получаем дату и время
        if (!getLocalTime(&timeinfo)) {
          Serial.println("Failed to obtain time");
          return;
        }
        Now1Min = timeinfo.tm_min;
        Now1Hour = timeinfo.tm_hour;
        Now1Day =  timeinfo.tm_mday;

        if (Now1Min != Old1Min) {                            // код который срабатывает 1 раз 1 минуту
          //Serial.println("Now1Min");
          Old1Min = Now1Min;
        }

        if ((Now1Min % 5 == 0) && (Now1Min != Old5Min)) {    // код который срабатывает 1 раз в 5 минут (5 минут статистика)
          //Serial.println("Now5Min");
          Old5Min = Now1Min;

          refreshOK = true;             // Отображаем на дисплее запрос данных

          OldShowcC = ShowcC;           // Сохраняем текущее значение комментариев

          getYoutubeChanel();           // Получаем количество подписчиков

          // обнуляем переменные для промежуточных расчетов
          wC = 0;                       // Количество просмотров
          lC = 0;                       // Количество лайков
          dC = 0;                       // Количество дизлайков
          cC = 0;                       // Количество комментариев

          // обновляем статистику по всем видео канала
          refreshA ();                  // Обновляем статистику

          // сохраняем предыдущую статистику (-10 минут)
          Last5Min [0] = Last5Min [1];  // Количество просмотров    OLD
          Last5Min [2] = Last5Min [3];  // Количество просмотров    OLD
          Last5Min [4] = Last5Min [5];  // Количество лайков        OLD
          Last5Min [6] = Last5Min [7];  // Количество комментариев  OLD

          // сохраняем сохраняем текущую статистику (последние -5 минут)
          Last5Min [1] = ShowwC;        // Количество просмотров    NEW
          Last5Min [3] = ShowlC;        // Количество просмотров    NEW
          Last5Min [5] = ShowdC;        // Количество лайков        NEW
          Last5Min [7] = ShowcC;        // Количество комментариев  NEW

          // обновляем данные 0 минут
          ShowwC = wC;                  // Количество просмотров - отдаем для отображения
          ShowlC = lC;                  // Количество лайков - отдаем для отображения
          ShowdC = dC;                  // Количество дизлайков - отдаем для отображения
          ShowcC = cC;                  // Количество комментариев - отдаем для отображения

          // если написали/удалили новый коментарий зажигаем синий светодиод
          if (OldShowcC != ShowcC) digitalWrite (BluL,HIGH);
       
          refreshOK = false;            // Данные получены
       
        }

        if ((Now1Min % 10 == 0) && (Now1Min != Old10Min)) {  // код который срабатывает 1 раз в 10 минут (прогноз погоды)
          Serial.println("Now10Min");
          Old10Min = Now1Min;
        }

        if (Now1Hour != Old1Hour) {                          // код который срабатывает 1 раз в час (статистика за 1 час)
          Serial.println("Now1Hour");
          Old1Hour = Now1Hour;

          // сохраняем предыдущую статистику (предыдущий час)
          Last1Hour [0] = Last1Hour [1];  // Количество просмотров   OLD
          Last1Hour [2] = Last1Hour [3];  // Количество просмотров   OLD
          Last1Hour [4] = Last1Hour [5];  // Количество лайков       OLD
          Last1Hour [6] = Last1Hour [7];  // Количество комментариев OLD

          // сохраняем сохраняем текущую статистику (текущий час)
          Last1Hour [1] = ShowwC;        // Количество просмотров    NEW
          Last1Hour [3] = ShowlC;        // Количество просмотров    NEW
          Last1Hour [5] = ShowdC;        // Количество лайков        NEW
          Last1Hour [7] = ShowcC;        // Количество комментариев  NEW

          // сохраняем статиситку за час во внутреннюю флеш память

          for (uint8_t i = 0; i < 32; i++) {
            EEPROM.write((Last1HourADDR + i), (*(Last1HourPTR + i)));
            EEPROM.commit();
          }

        }

        if (Now1Day != Old1Day) {                            // код который срабатывает 1 раз в сутки (статистика за 1 сутки)
          // синхронизируем внутренние часы со временем из интернет
          configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
          Serial.println("Now1Day");
          Old1Day = Now1Day;

          // сохраняем предыдущую статистику (предыдущие сутки до 00:00)
          Last1Day [0] = Last1Day [1];  // Количество просмотров    OLD
          Last1Day [2] = Last1Day [3];  // Количество просмотров    OLD
          Last1Day [4] = Last1Day [5];  // Количество лайков        OLD
          Last1Day [6] = Last1Day [7];  // Количество комментариев  OLD

          // сохраняем сохраняем текущую статистику (текущие сутки до 00:00)
          Last1Day [1] = ShowwC;        // Количество просмотров    NEW
          Last1Day [3] = ShowlC;        // Количество просмотров    NEW
          Last1Day [5] = ShowdC;        // Количество лайков        NEW
          Last1Day [7] = ShowcC;        // Количество комментариев  NEW

          // сохраняем статиситку за день во внутреннюю флеш память
          for (uint8_t i = 0; i < 32; i++) {
            EEPROM.write((Last1DayADDR + i), (*(Last1DayPTR + i)));
            EEPROM.commit();
          }
        }

        delay(10);
      }

    }
     
    NikitOS нравится это.
  4. issaom

    issaom Гуру

    ESP32_fourBtSens.h

    Код (C++):
    #define bt1 14      //Кнопка 1 GPIO 14
    #define bt2 27      //Кнопка 2 GPIO 27
    #define bt3 12      //Кнопка 3 GPIO 12
    #define bt4 13      //Кнопка 4 GPIO 13

    uint8_t BtF1 = 1;   // Фильтр от ложных срабатываний Кнопка 1
    uint8_t BtF2 = 1;   // Фильтр от ложных срабатываний Кнопка 2
    uint8_t BtF3 = 1;   // Фильтр от ложных срабатываний Кнопка 3
    uint8_t BtF4 = 1;   // Фильтр от ложных срабатываний Кнопка 4
    uint8_t StBt = 0;   // переменная для хранения статуса 4х кнопок младший бит нажата/старший обработана 2х4=8
    const uint8_t SensThreshold = 50; //порог срабатывания сенсора
    const uint8_t filtrCount = 3;     // сколько проверок выполнять для определения состояния кнопки (max7 bit)
                                      // если будут самонажиматься кнопки - увеличить число (максимум до 7)

    // возвращаем статус 4х кнопок младший бит нажата/старший обработана 2х4=8
    void readBtSens () {

      // Если прикоснулись к 1-й сенсорной кнопке
      if ((touchRead(bt1)) < SensThreshold) {
        if (bitRead(BtF1, filtrCount)) bitSet(StBt, 0); else BtF1 <<= 1;
      }
      else {                          // Не касаемся сенсорной кнопки
        if (bitRead(BtF1, 0)) {
          bitClear(StBt, 0); bitClear(StBt, 1);
        } else BtF1 >>= 1;
      }

      // Если прикоснулись к 2-й сенсорной кнопке
      if ((touchRead(bt2)) < SensThreshold) {
        if (bitRead(BtF2, filtrCount)) bitSet(StBt, 2); else BtF2 <<= 1;
      }
      else {                          // Не касаемся сенсорной кнопки
        if (bitRead(BtF2, 0)) {
          bitClear(StBt, 2); bitClear(StBt, 3);
        } else BtF2 >>= 1;
      }

      // Если прикоснулись к 3-й сенсорной кнопке
      if ((touchRead(bt3)) < SensThreshold) {
        if (bitRead(BtF3, filtrCount)) bitSet(StBt, 4); else BtF3 <<= 1;
      }
      else {                          // Не касаемся сенсорной кнопки
        if (bitRead(BtF3, 0)) {
          bitClear(StBt, 4); bitClear(StBt, 5);
        } else BtF3 >>= 1;
      }

      // Если прикоснулись к 4-й сенсорной кнопке
      if ((touchRead(bt4)) < SensThreshold) {
        if (bitRead(BtF4, filtrCount)) bitSet(StBt, 6); else BtF4 <<= 1;
      }
      else {                          // Не касаемся сенсорной кнопки
        if (bitRead(BtF4, 0)) {
          bitClear(StBt, 6); bitClear(StBt, 7);
        } else BtF4 >>= 1;
      }

    }
     
    NikitOS нравится это.
  5. issaom

    issaom Гуру

    ESP32_youtubeA.h

    Код (C++):
    // Создание полного списка видео
    void makeVideoList () {

      if (WiFi.status() == WL_CONNECTED) {
        wifiOK = true;
        AllVideoList = "";  // Обнуляем существующий список видео
        AllVideoCount = 0;  // Обнуляем количество найденых и внесенных видео в файле
        int32_t findStart = 0; int32_t findNext = 0; int32_t findEnd = 0;

        // Получаем ссылку на плейлист "загрузки"
        String serverPath = "https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id=" + youtubeNameChammel + "&key=" + youtubeApiKey;
        String S = httpGETRequest(serverPath.c_str());
        String uploads = "";
        findStart = S.indexOf("\"uploads", findNext);
        findNext = findStart + 12;
        findEnd = S.indexOf("\"", findNext);
        uploads = S.substring(findNext, findEnd);
        delay(25);

        // Получаем и сохраняем ID первые 30 видео и получаем ссылку на следующие 30
        serverPath = "https://www.googleapis.com/youtube/v3/playlistItems?playlistId=" + uploads + "&maxResults=30&key=" + youtubeApiKey + "&part=contentDetails";
        S = httpGETRequest(serverPath.c_str());

        // херачим найденые видео в список по 11 символов + запятая
        findStart = 0; findNext = 0; findEnd = 0;
        findStart = S.indexOf("\"videoId", findNext);
        while ( findStart != -1) {
          findNext = findStart + 12;
          findEnd = S.indexOf("\"", findNext);
          AllVideoList = AllVideoList + S.substring(findNext, findEnd);
          AllVideoList = AllVideoList + ",";
          AllVideoCount++;
          ShowvC = AllVideoCount;                       //отдаем на отображение
          findStart = S.indexOf("\"videoId", findEnd);
        }

        // получаем ссылку на следующую страничку
        String nextPageToken = "";
        findStart = 0; findNext = 0; findEnd = 0;
        findStart = S.indexOf("\"nextPageToken", findNext);
        if (findStart == -1) return; //на канале меньше 30 видео - миссия комплит
        findNext = findStart + 18;
        findEnd = S.indexOf("\"", findNext);
        nextPageToken = S.substring(findNext, findEnd);

    label:
        serverPath = "https://www.googleapis.com/youtube/v3/playlistItems?playlistId=" + uploads + "&maxResults=30&key=" + youtubeApiKey + "&part=contentDetails&pageToken=" + nextPageToken;
        S = httpGETRequest(serverPath.c_str());

        // херачим найденые видео в список по 11 символов + запятая
        findStart = 0; findNext = 0; findEnd = 0;
        findStart = S.indexOf("\"videoId", findNext);
        while ( findStart != -1) {
          findNext = findStart + 12;
          findEnd = S.indexOf("\"", findNext);
          AllVideoList = AllVideoList + S.substring(findNext, findEnd);
          AllVideoList = AllVideoList + ",";
          AllVideoCount++;
          ShowvC = AllVideoCount;                       //отдаем на отображение
          findStart = S.indexOf("\"videoId", findEnd);
        }

        // получаем ссылку на следующую страничку
        nextPageToken = "";
        findStart = 0; findNext = 0; findEnd = 0;
        findStart = S.indexOf("\"nextPageToken", findNext);
        if (findStart == -1) return; // nextPageToken не найден - дошли до последней странички
        findNext = findStart + 18;
        findEnd = S.indexOf("\"", findNext);
        nextPageToken = S.substring(findNext, findEnd);
        delay(25);
        goto label;

      } else {
        // нет подключения
        wifiOK = false;
      }

    }


    // Запрос статистики по каналу
    void getYoutubeChanel() {
      if (WiFi.status() == WL_CONNECTED) {
        wifiOK = true;
        // информация о количестве подписчиков
        String serverPath = "https://www.googleapis.com/youtube/v3/channels?part=statistics&id=" + youtubeNameChammel + "&key=" + youtubeApiKey;
        // Запрашиваем строку json
        String S = httpGETRequest(serverPath.c_str());
        // Получаем количество подписчиков
        String s; int32_t findStart = 0; int32_t findNext = 0; int32_t findEnd = 0;
        findStart = S.indexOf("\"subscriberCount", findNext);
        findNext = findStart + 20;
        findEnd = S.indexOf("\"", findNext);
        s = S.substring(findNext, findEnd);
        ShowsC = s.toInt();
        delay(25);

      } else {
        // нет подключения
        wifiOK = false;
      }
    }

    // Запрос агрегатной статистики от 1 до 50-ти видео
    // Входной параметр сторока вида: idvideo1,idvideo2,....,idvideo50
    void getYoutubeVideoS(String listVideo) {

      if (WiFi.status() == WL_CONNECTED) {
     
        wifiOK = true;

        String serverPath = "https://www.googleapis.com/youtube/v3/videos?id=" + listVideo + "&key=" + youtubeApiKey + "&part=statistics";
        String S = httpGETRequest(serverPath.c_str());

        String s = ""; int32_t findStart = 0; int32_t findNext = 0; int32_t findEnd = 0;
        uint32_t viewCount = 0;                          //парсим количество просмотров
        findStart = S.indexOf("\"viewCount", findNext);
        while ( findStart != -1) {
          findNext = findStart + 14;
          findEnd = S.indexOf("\"", findNext);
          s = S.substring(findNext, findEnd);
          viewCount = viewCount + s.toInt();
          //Serial.println(s.toInt());
          findStart = S.indexOf("\"viewCount", findEnd);
        }

        s = ""; findStart = 0; findNext = 0; findEnd = 0;
        uint32_t likeCount = 0;                          //парсим количество лайков
        findStart = S.indexOf("\"likeCount", findNext);
        while ( findStart != -1) {
          findNext = findStart + 14;
          findEnd = S.indexOf("\"", findNext);
          s = S.substring(findNext, findEnd);
          likeCount = likeCount + s.toInt();
          //Serial.print(s.toInt()); Serial.print(" - ");
          findStart = S.indexOf("\"likeCount", findNext);
        }

        s = ""; findStart = 0; findNext = 0; findEnd = 0;
        uint32_t dislikeCount = 0;                        //парсим количество дизлайков
        findStart = S.indexOf("\"dislikeCount", findNext);
        while ( findStart != -1) {
          findNext = findStart + 17;
          findEnd = S.indexOf("\"", findNext);
          s = S.substring(findNext, findEnd);
          dislikeCount = dislikeCount + s.toInt();
          //Serial.print(s.toInt()); Serial.print(" - ");
          findStart = S.indexOf("\"dislikeCount", findNext);
        }

        s = ""; findStart = 0; findNext = 0; findEnd = 0;
        uint32_t commentCount = 0;                        //парсим количество коментариев
        findStart = S.indexOf("\"commentCount", findNext);
        while ( findStart != -1) {
          findNext = findStart + 17;
          findEnd = S.indexOf("\"", findNext);
          s = S.substring(findNext, findEnd);
          commentCount = commentCount + s.toInt();
          //Serial.print(s.toInt()); Serial.println(" - ");
          findStart = S.indexOf("\"commentCount", findNext);
        }

        wC = wC + viewCount;                     // Количество просмотров
        lC = lC + likeCount;                     // Количество лайков
        dC = dC + dislikeCount;                  // Количество дизлайков
        cC = cC + commentCount;                  // Количество комментариев

      } else {
        // нет подключения - придумаю чуть позже
        wifiOK = false;
      }
    }

    void refreshA () {

      uint32_t remainVideo = AllVideoCount;
      String S = AllVideoList;
      String s = "";

    label:

      if (remainVideo <= 30) {                   // Разбираем остаток
        S.remove(S.lastIndexOf(','));            // Удаляем последнюю запятую
        getYoutubeVideoS(S);  
        return;
      }

      do {                                       // Делаем запрос по 30 видео
        s = S.substring(0, 360);
        s.remove(s.lastIndexOf(','));
        S.remove(0, 360);
        getYoutubeVideoS(s);
        remainVideo = remainVideo - 30;
        delay(25);
      } while (remainVideo > 30);

      goto label;
    }
     
    NikitOS нравится это.
  6. issaom

    issaom Гуру

    Ну и как обычно не кому не нужный видик

     
    OldKryptos и NikitOS нравится это.