Fun with YouTube Data API v3 (Public Data) and Kigs Framework

9 Jul 2020MIT
Kigs framework C++ Windows project to retrieve and display what other channels are subscribed by subscribers of a given YouTube channel.
I took advantage of this period of quarantine to play with the functionality of the Kigs framework. In this article, you will see how to develop a simple Windows application to do HTTPS requests on Youtube Data API v3, retrieve JSON data, download YouTube thumbnails and display results using the Kigs framework.

Table of Contents

Introduction

Kigs framework is an open-source (MIT Licence), free, C++, multi-purpose and cross-platform framework that you can find at https://github.com/Kigs-framework/kigs.

The application presented here displays statistics on Youtube Channels subscribed by users subscribing to a given Channel.

To do this, the application first retrieves videos of a given YouTube Channel, then retrieves comments from each video, and for each comment's writer tests if the writer's subscriptions are public.

If yes, the application checks if the writer subscribes to the given Youtube Channel and if yes again, adds other writer's subscribed channels to the statistics.

In the following image, we can see that for about 50 Kurzgesagt subscribers found, 46% subscribes to PewDiePie, 38% to VSauce and 32% to TED Ed.

Image 1

Background

Image 2

A series of articles was started here on Code Project. You can have a look at the first article here:

Of course, you can read the present article without first reading the Kigs framework introduction series.

We would be happy to be joined by people wishing to participate in the use and improvement of the Kigs framework.

Google API Key

To execute the code, you will need to create a Google API Key. You can freely create and use a (limited) API Key.

Register with a Google account at https://console.developers.google.com.

Create a new project and on the Credentials page, click Create credentials > API key.

Then create an API key for "Youtube Data API v3", for the platform, choose "other platform..." and public data.

Building the Code

To build the code, you will have to clone the framework from GitHub and set up the development environment for Windows platform (Visual C++, CMake). Check https://github.com/Kigs-framework/kigs/wiki/Getting-Started.

Then extract the project in the kigs\projects folder.

In this folder, open CMakeLists.txt file with a text editor and add the line:

add_subdirectory(YoutubeAnalyser)

Then execute (double click) kigs\scripts\generateWinCMake.bat.

Browse to generated Build\solutionWinCMake\kigs\projects\YoutubeAnalyser folder.

And double click on YoutubeAnalyser.sln to open the solution in Visual Studio.

In Visual Studio, select YoutubeAnalyser as your startup project. Select StaticDebug or StaticRelease configuration and build.

Executing the Code

Before executing the code, you will have to edit configuration file at kigs\projects\YoutubeAnalyser\Data\launchParams.json.

Open it in a text editor. You will find this:

{
   "GoogleKey" : "INSERT_YOUR_GOOGLE_KEY_HERE",
   "ChannelID" : "INSERT_CHANNEL_ID_HERE",
   "ValidUserCount" : 100,
   "MaxChannelCount" : 40,
   "ValidChannelPercent" : 0.02,
}

Replace INSERT_YOUR_GOOGLE_KEY_HERE by your previously generated Key.

Then go to YouTube, choose one of your favorite channels (in this article, I will use "Kurzgesagt – In a Nutshell") and look at the URL, https://www.youtube.com/channel/UCsXVk37bltHxD1rDPwtNM8Q.

If URL doesn't contains channel ID, you can also look at the source code of the page and search for : 

<link rel="canonical" href="###"> to find the good ID.

Copy the channel ID UCsXVk37bltHxD1rDPwtNM8Q and replace INSERT_CHANNEL_ID_HERE by the wanted channel ID.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

Save and close launchParams.json. You can now execute the project in Visual C++.

Image 3

Dive Into the Code

We will now see how the Kigs framework can be used to do several things.

Manipulating a JSON File

YouTubeAnalyser class has the following members:

// general application parameters

std::string                     mKey = "";
std::string                     mChannelName;
unsigned int                    mSubscribedUserCount = 100;
unsigned int                    mMaxChannelCount = 16;
int                             mMaxUserPerVideo = 0;
float                           mValidChannelPercent = 0.02f;

And at application start, we want to retrieve the values stored in launchParams.json.

This is done with the following code in YoutubeAnalyser.cpp (around line 50):

JSonFileParser L_JsonParser;
CoreItemSP initP = L_JsonParser.Get_JsonDictionary("launchParams.json");

// retreive parameters
mKey = "&key=" + (std::string)initP["GoogleKey"];
mChannelName = initP["ChannelID"];

if (!initP["ValidUserCount"].isNil())
    mSubscribedUserCount = initP["ValidUserCount"];

if (!initP["MaxChannelCount"].isNil())
    mMaxChannelCount = initP["MaxChannelCount"];

if (!initP["ValidChannelPercent"].isNil())
    mValidChannelPercent = initP["ValidChannelPercent"];

if (!initP["MaxUserPerVideo"].isNil())
    mMaxUserPerVideo = initP["MaxUserPerVideo"];

As you can see, the process is really simple: create a JSonFileParser instance, call Get_JsonDictionary with the filename as parameter and store the result in CoreItemSP initP instance.

Then you can search if values are available on a CoreItemSP instance using isNil() method, accessing them with initP["searched object"].

More complex JSON data access is done in other parts of the code (around line 1100 for example):

for (int i = 0; i < commentThreads->size(); i++)
{
   CoreItemSP topComment = commentThreads[i]["snippet"]["topLevelComment"]["snippet"];
   if (!topComment.isNil())
   {
        std::string authorID = topComment["authorChannelId"]["value"];
        // ...
   }
}

Creating a JSON like object and saving it is also easy (around line 860):

JSonFileParser L_JsonParser;

std::string filename = "Cache/" + mChannelName + "/videos/";
filename += videoID + "_videos.json";

CoreItemSP initP= CoreItemSP::getCoreMap();
CoreItemSP v = CoreItemSP::getCoreVector();
for (const auto& auth : mAuthorListToProcess)
{
   v->set("", CoreItemSP::getCoreValue(auth));
}

initP->set("authors", v);

L_JsonParser.Export((CoreMap<std::string>*)initP.get(), filename);

HTTP GET Request

Public YouTube data are accessed by doing GET HTTP requests (HTTPS in fact).

With the Kigs framework, we first need to create the HTTPRequest Module in the application initialization method, YoutubeAnalyser::ProtectedInit().

CoreCreateModule(HTTPRequestModule, 0);

Then a HTTPConnect instance is created and initialized:

// ask for an instance of class HTTPConnect 
mGoogleConnect = KigsCore::GetInstanceOf("googleConnect", "HTTPConnect");
// set HostName
mGoogleConnect->setValue("HostName", "www.googleapis.com");
// set connection type ( HTTP or HTTPS )
mGoogleConnect->setValue("Type", "HTTPS");
// set Port to default HTTPS port
mGoogleConnect->setValue("Port", "443");
// initialize instance with given parameters
mGoogleConnect->Init();

Then each time an HTTP GET request is needed, an instance of HTTPRequest is created:

// encode request in URL
std::string url = "/youtube/v3/channels?part=snippet&id=";
std::string request = url + mChannelName + mKey;
// then ask HTTPConnect to create a HTTPRequest instance
// parameters are:
// - the request itself
// - the callback to call when results are received
// - the object on which callback is called
mAnswer = mGoogleConnect->retreiveGetAsyncRequest(request.c_str(), "getChannelID", this);
// initialize the instance to really send the request
mAnswer->Init();

Kigs framework callbacks are declared like this (here in YoutubeAnalyser.h) :

DECLARE_METHOD(getChannelID);
DECLARE_METHOD(getChannelPage);
DECLARE_METHOD(getVideoList);
// ...
COREMODIFIABLE_METHODS(getChannelID, getVideoList, getChannelPage);

Then a callback is defined like this (here in YoutubeAnalyser.cpp around line 780):

DEFINE_METHOD(YoutubeAnalyser, getChannelID)
{
   auto json=RetrieveJSON(sender);
   if (!json.isNil())
   {
      CoreItemSP IDItem = json["items"][0]["id"];
      // ... 

Displaying Results

The main screen is defined with the XML file, YoutubeAnalyser\Data\assets\Screen_Main.xml.

This file starts like this:

<?xml version="1.0" encoding="iso-8859-1"?>
<Inst N="sequencemain" T="DataDrivenSequence">

Each time a new sequence is initialized in a Data-Driven Kigs framework application, the method ProtectedInitSequence is called with the sequence name as a parameter.

In YoutubeAnalyser.cpp (around line 665), the method is defined like this:

void    YoutubeAnalyser::ProtectedInitSequence(const kstl::string& sequence)
{
    if (sequence == "sequencemain")
    {
        mMainInterface = GetFirstInstanceByName("UIItem", "Interface");
    }
}

The sequence name, "sequencemain", is defined in the Screen_Main.xml as seen previously. So here, we will search for an instance of class UIItem (base class for all 2D elements) named "Interface" in all the framework instanced objects and store it in member variable mMainInterface.

In the same Screen_Main.xml, the Interface UIItem has (among others) a UITexture son named "thumbnail", itself having a UIText son named "ChannelName":

<Inst N="Interface" T="UIItem">
   <Attr N="SizeY" V="800"/>
   <Attr N="SizeX" V="1280"/>
   <Inst N="thumbnail" T="UITexture">
      <Attr N="Priority" V="48"/>
      <Attr N="Dock" V="{0.5,0.5}"/>
      <Attr N="Anchor" V="{0.5,0.5}"/>
      <Inst N="ChannelName" T="UIText">
         <Attr N="Priority" V="47"/>
         <Attr N="Text" V="channelName"/>
         <Attr N="Dock" V="{0.5,1.0}"/>
         <Attr N="Anchor" V="{0.5,0.0}"/>
         <Attr N="SizeX" V="-1"/>
         <Attr N="SizeY" V="-1"/>
         <Attr N="Font" V="Calibri.ttf"/>
         <Attr N="FontSize" V="20"/>
         <Attr N="MaxWidth" V="200"/>        
      </Inst>
   </Inst>
</Inst>

In YoutubeAnalyser.cpp (around line 360), we will set the texture and name of the channel:

if (mMainInterface)
{
   // check if Channel texture was loaded
   if (mChannelInfos.mThumb.mTexture && mMainInterface["thumbnail"])
   {
      // cast to UITexture smartpointer reference
      const SP<UITexture>& tmp = mMainInterface["thumbnail"];

      // texture was not already set ?
      if (!tmp->GetTexture())
      {
         // add texture
         tmp->addItem(mChannelInfos.mThumb.mTexture);
         // set "Text" value on "ChannelName" instance son of "thumbnail" instance
         // son of mMainInterface instance 
         mMainInterface["thumbnail"]["ChannelName"]("Text") = mChannelInfos.mName;
      }
   }
}

Conclusion

The free Google API Key is limited so that our application can only do a limited amount of requests per day. But all requests are cached in files, so when the limit is reached, you can close the app and execute it again the next day to go further.

In this article, we have seen some of the Kigs framework features:

  • Manipulate JSON files or objects
  • Create and manipulate instances of the framework's classes
  • XML serialization, 2D display
  • ...

If you liked this article, feel free to rate it, read Kigs framework Introduction series, and join us using the Kigs framework and helping us to make it live and grow.

History

  • 13th April, 2020: First release
  • 01st May, 2020: Kigs-framework GitHub repo was moved
  • 09th July, 2020: fixed some bug, better error management.
 

License

This article, along with any associated source code and files, is licensed under The MIT License

About the Author

Stephane Capo
Chief Technology Officer NEXT-BIM
 
France France
CTO of NEXT-BIM, I also supervise and participate in the development of Kigs framework.
 
 
 
 
본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
174 [Unix/Linux][유닉스/리눅스] chmod [권한변경] /bin/chmod 졸리운_곰 2021.02.14 247
173 How to Install Dev-C++ and the GLUT Libraries for Compiling OpenGL Programs with ANSI C file 졸리운_곰 2021.02.02 321
172 [무료 리눅스 linux 백신, 안티바이러스] 무료 리눅스 백신 ClamAV 이용 및 문제 해결법 졸리운_곰 2021.02.01 342
171 [C/C++] 미니멀 가상화폐 코드 , 미니멀 블룩체인, noincoin (Block Chain in C Major) file 졸리운_곰 2021.01.30 279
170 리눅스 tee, 화면과 파일에 동시 출력하기 졸리운_곰 2021.01.21 395
169 [C/C++ 네트워크 프로그래밍] POCO 라이브러리의 특징 졸리운_곰 2021.01.06 643
168 Visual Studio Community로 V8 엔진 다운로드 및 빌드하고 간단히 살펴보기 file 졸리운_곰 2020.11.30 271
167 [Linux] [C/C++] CMake를 이용한 패키지 빌드 file 졸리운_곰 2020.11.08 297
166 [Linux][C/C++] cmake 사용법과 활용 file 졸리운_곰 2020.11.08 552
165 [CMake] Linux C/C++ cmake 시작하기 졸리운_곰 2020.11.08 398
164 [C++] CMake Build System file 졸리운_곰 2020.11.08 328
163 [리눅스, Linux] YUM 명령어 정리 file 졸리운_곰 2020.11.07 322
162 자바(Java) instanceof 사용방법 졸리운_곰 2020.10.29 328
161 Building libtorrent with Visual Studio file 졸리운_곰 2020.10.25 309
160 [분석할 소스] microPython 마이크로 파이썬 소스 file 졸리운_곰 2020.10.18 348
159 [분석할 소스] MicroPython.js MicroPython transmuted into Javascript by Emscripten. file 졸리운_곰 2020.10.18 250
158 [리눅스, linux] 프로세스를 이름으로 단번에 종료하기 졸리운_곰 2020.08.17 497
» Fun with YouTube Data API v3 (Public Data) and Kigs Framework file 졸리운_곰 2020.07.19 314
156 Kigs Framework Introduction (8/8) - Data Driven Application file 졸리운_곰 2020.07.18 302
155 ubuntu 18.04 - Ubuntu 한글 입력기 설치(fcitx) file 졸리운_곰 2020.06.29 334
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED