├── res ├── embeds.png ├── Example1.png └── Example2.png ├── assets ├── close.html ├── images │ ├── banner.jpg │ ├── icon.png │ ├── sharing.png │ ├── sharing.pvc.png │ └── sharing.pvt.png ├── js │ ├── query.vs.js │ ├── live.core.js │ ├── live.view.js │ ├── live.vs.js │ ├── urlManager.view.js │ ├── base.js │ ├── urlManager.core.js │ ├── query.view.js │ ├── urlManager.vs.js │ ├── updateManager.vs.js │ ├── sharing.view.js │ ├── sharing.core.js │ ├── updateManager.core.js │ ├── query.core.js │ ├── updateManager.view.js │ ├── custom-ui.js │ ├── init.js │ ├── featured.view.js │ ├── featured.core.js │ ├── multisearch.core.js │ ├── multisearch.view.js │ ├── multisearch.vs.js │ ├── sharing.vs.js │ └── waves.js └── css │ ├── stylevs.css │ ├── odometer-theme-custom.css │ ├── colors │ └── light.css │ └── style.css ├── .gitignore ├── 404.html ├── package.json ├── README.md ├── compare └── index.html ├── live-view-count └── index.html ├── pewdiepie-vs-mrbeast └── index.html ├── pewdiepie-vs-cocomelon └── index.html └── index.html /res/embeds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/res/embeds.png -------------------------------------------------------------------------------- /res/Example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/res/Example1.png -------------------------------------------------------------------------------- /res/Example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/res/Example2.png -------------------------------------------------------------------------------- /assets/close.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.psd 2 | .htaccess 3 | _internal 4 | # Local Netlify folder 5 | .netlify 6 | node_modules 7 | -------------------------------------------------------------------------------- /assets/images/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/assets/images/banner.jpg -------------------------------------------------------------------------------- /assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/assets/images/icon.png -------------------------------------------------------------------------------- /assets/images/sharing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/assets/images/sharing.png -------------------------------------------------------------------------------- /assets/images/sharing.pvc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/assets/images/sharing.pvc.png -------------------------------------------------------------------------------- /assets/images/sharing.pvt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akshatmittal/youtube-realtime/HEAD/assets/images/sharing.pvt.png -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

404

5 |

We will redirect you to the home page in 3 seconds.

6 | 15 | -------------------------------------------------------------------------------- /assets/js/query.vs.js: -------------------------------------------------------------------------------- 1 | YT.query = { 2 | begin: function () { 3 | $.getJSON( 4 | "https://mixerno.space/api/youtube-channel-counter/user/" + encodeURIComponent(YT.live.vs1), 5 | function (f) { 6 | $.getJSON( 7 | "https://mixerno.space/api/youtube-channel-counter/user/" + encodeURIComponent(YT.live.vs2), 8 | function (g) { 9 | YT.updateManager.updateCover(f.user[2].count, g.user[2].count); 10 | YT.updateManager.updateName(f.user[0].count, g.user[0].count); 11 | YT.updateManager.updateProfile(f.user[1].count, g.user[1].count); 12 | }, 13 | ); 14 | }, 15 | ); 16 | }, 17 | bind: function () {}, 18 | }; 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "youtube-realtime", 3 | "version": "1.0.0", 4 | "description": "Live YouTube Subscriber Count", 5 | "scripts": { 6 | "start": "http-server --ssl --cert _internal\\ssl.cert --key _internal\\ssl.key -a local.akshatmittal.com -p 8443", 7 | "serve": "npx serve@latest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/akshatmittal/youtube-realtime.git" 12 | }, 13 | "author": "Akshat Mittal", 14 | "bugs": { 15 | "url": "https://github.com/akshatmittal/youtube-realtime/issues" 16 | }, 17 | "homepage": "https://akshatmittal.com/youtube-realtime/", 18 | "dependencies": { 19 | "http-server": "^0.12.3" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /assets/js/live.core.js: -------------------------------------------------------------------------------- 1 | YT.live = { 2 | channelID: "", 3 | update: function () { 4 | $.getJSON("https://mixerno.space/api/youtube-channel-counter/user/" + this.channelID, function (e) { 5 | if (e) { 6 | YT.updateManager.updateSubscribers(e.counts[2].count); 7 | YT.updateManager.updateViews(e.counts[3].count); 8 | YT.updateManager.updateVideos(e.counts[5].count); 9 | } else { 10 | YT.query.newSearch(YT.live.channelID); 11 | } 12 | }); 13 | }, 14 | timer: null, 15 | start: function () { 16 | this.stop(); 17 | this.timer = setInterval(function (e) { 18 | YT.live.update(); 19 | }, 2000); 20 | YT.live.update(); 21 | }, 22 | stop: function () { 23 | clearInterval(this.timer); 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /assets/js/live.view.js: -------------------------------------------------------------------------------- 1 | YT.live = { 2 | channelID: "", 3 | update: function () { 4 | $.getJSON("https://mixerno.space/api/youtube-video-counter/user/" + this.channelID, function (e) { 5 | if (e) { 6 | YT.updateManager.updateViews(e.counts[2].count); 7 | YT.updateManager.updateLikes(e.counts[3].count); 8 | YT.updateManager.updateDislikes(e.counts[4].count); 9 | YT.updateManager.updateComments(e.counts[5].count); 10 | } else { 11 | YT.query.newSearch(YT.live.channelID); 12 | } 13 | }); 14 | }, 15 | timer: null, 16 | start: function () { 17 | this.stop(); 18 | this.timer = setInterval(function (e) { 19 | YT.live.update(); 20 | }, 2000); 21 | YT.live.update(); 22 | }, 23 | stop: function () { 24 | clearInterval(this.timer); 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /assets/js/live.vs.js: -------------------------------------------------------------------------------- 1 | YT.live = { 2 | vs1: "", 3 | vs2: "", 4 | update: function () { 5 | $.getJSON("https://mixerno.space/api/youtube-channel-counter/user/" + YT.live.vs1, function (f) { 6 | $.getJSON("https://mixerno.space/api/youtube-channel-counter/user/" + YT.live.vs2, function (g) { 7 | YT.updateManager.updateSubscribers(f.counts[2].count, g.counts[2].count); 8 | }); 9 | }); 10 | }, 11 | timer: null, 12 | setVS: function (e, f) { 13 | this.vs1 = e; 14 | this.vs2 = f; 15 | this.start(); 16 | }, 17 | start: function () { 18 | this.stop(); 19 | YT.query.begin(); 20 | this.timer = setInterval(function (e) { 21 | YT.live.update(); 22 | }, 10000); 23 | YT.live.update(); 24 | }, 25 | stop: function () { 26 | clearInterval(this.timer); 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /assets/js/urlManager.view.js: -------------------------------------------------------------------------------- 1 | YT.urls = { 2 | onchange: function () { 3 | var q = location.hash.split("!/")[1]; 4 | if (q) { 5 | YT.query.newSearch(location.hash.split("!/")[1]); 6 | } else { 7 | var coolGuys = ["9bZkp7q19f0", "YQHsXMglC9A", "60ItHLz5WEA", "pk7ESz6vtyA", "gwMa6gpoE9I"]; 8 | YT.query.newSearch(coolGuys[Math.floor(Math.random() * coolGuys.length)]); 9 | } 10 | }, 11 | pushState: function (e) { 12 | history.pushState(null, null, "#!/" + e); 13 | DISQUS.reset({ 14 | reload: true, 15 | config: function () { 16 | this.page.identifier = e; 17 | this.page.url = baseURL + "live-view-count/#!/" + e; 18 | }, 19 | }); 20 | YT.query.newSearch(e); 21 | }, 22 | getCurrent: function () { 23 | return baseURL + "live-view-count/#!/" + YT.live.channelID; 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /assets/js/base.js: -------------------------------------------------------------------------------- 1 | var baseURL = "https://gh.akshatmittal.com/youtube-realtime/"; 2 | if (typeof isCustomPage == "undefined") isCustomPage = 0; 3 | // if (window.location.hostname.indexOf("local.akshatmittal.com") < 0) { 4 | // if (window.location.protocol != "https:") window.location.replace("https:" + window.location.href.substring(window.location.protocol.length)); 5 | // if (location.hostname.indexOf("akshatmittal.com") == -1) window.location.replace(baseURL + location.hash); 6 | // if (window.top !== window.self) window.top.location.replace(window.self.location.href); 7 | // } 8 | Array.prototype.shuffle = function () { 9 | var i = this.length, 10 | j, 11 | temp; 12 | if (i == 0) return this; 13 | while (--i) { 14 | j = Math.floor(Math.random() * (i + 1)); 15 | temp = this[i]; 16 | this[i] = this[j]; 17 | this[j] = temp; 18 | } 19 | return this; 20 | }; 21 | var YT = {}; 22 | -------------------------------------------------------------------------------- /assets/js/urlManager.core.js: -------------------------------------------------------------------------------- 1 | YT.urls = { 2 | onchange: function () { 3 | var q = location.hash.split("!/")[1]; 4 | if (q) { 5 | YT.query.newSearch(location.hash.split("!/")[1]); 6 | } else { 7 | var coolGuys = [ 8 | "UCBJycsmduvYEL83R_U4JriQ", 9 | "UCtinbF-Q-fVthA0qrFQTgXQ", 10 | "UCp0hYYBW6IMayGgR-WeoCvQ", 11 | "UCBJycsmduvYEL83R_U4JriQ", 12 | ]; 13 | YT.query.newSearch(coolGuys[Math.floor(Math.random() * coolGuys.length)]); 14 | } 15 | }, 16 | pushState: function (e) { 17 | history.pushState(null, null, "#!/" + e); 18 | DISQUS.reset({ 19 | reload: true, 20 | config: function () { 21 | this.page.identifier = e; 22 | this.page.url = baseURL + "#!/" + e; 23 | }, 24 | }); 25 | YT.query.newSearch(e); 26 | }, 27 | getCurrent: function () { 28 | return baseURL + "#!/" + YT.live.channelID; 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /assets/css/stylevs.css: -------------------------------------------------------------------------------- 1 | .page-wrapper { 2 | margin-left: 0 !important; 3 | } 4 | 5 | .footer { 6 | left: 0 !important; 7 | text-align: center; 8 | } 9 | 10 | .container { 11 | width: auto !important; 12 | max-width: 1440px; 13 | } 14 | 15 | .navbar-header { 16 | width: 100%; 17 | } 18 | 19 | .navbar-brand { 20 | font-size: 1.65em; 21 | } 22 | 23 | .display-1 { 24 | font-size: 7rem !important; 25 | } 26 | 27 | .display-title { 28 | text-align: center; 29 | } 30 | 31 | @media (max-width: 1260px) { 32 | .display-1 { 33 | font-size: 6rem !important; 34 | } 35 | } 36 | 37 | @media (max-width: 1100px) { 38 | .display-1 { 39 | font-size: 5rem !important; 40 | } 41 | } 42 | 43 | @media (max-width: 950px) { 44 | .display-1 { 45 | font-size: 4.2rem !important; 46 | } 47 | } 48 | 49 | @media (max-width: 820px) { 50 | .display-1 { 51 | font-size: 3.5rem !important; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /assets/js/query.view.js: -------------------------------------------------------------------------------- 1 | YT.query = { 2 | newSearch: function (e) { 3 | if (e.trim() == YT.live.channelID || e.trim() == "") { 4 | return; 5 | } 6 | YT.live.stop(); 7 | $.getJSON("https://mixerno.space/api/youtube-video-counter/search/" + encodeURIComponent(e), function (e) { 8 | if (!e.list || e.list.length === 0) { 9 | alert("No results found!"); 10 | return; 11 | } 12 | YT.updateManager.updateChannelID(e.list[0][2]); 13 | YT.updateManager.updateCover(e.list[0][1]); 14 | YT.updateManager.updateName(e.list[0][0]); 15 | YT.updateManager.updateProfile(e.list[0][1]); 16 | YT.urls.pushState(e.list[0][2]); 17 | YT.live.start(); 18 | }); 19 | }, 20 | search: function (e) { 21 | e.preventDefault(); 22 | YT.query.newSearch($("#yt_searchvalue").val()); 23 | $("#yt_searchvalue").val(""); 24 | }, 25 | bind: function () { 26 | $("#yt_search").on("submit", this.search); 27 | $("#yt_searchbutton").on("click", this.search); 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /assets/js/urlManager.vs.js: -------------------------------------------------------------------------------- 1 | YT.urls = { 2 | onchange: function () { 3 | var q = location.hash.split("!/")[1]; 4 | if (q) { 5 | var q = q.split("$$"); 6 | if (q[0] > q[1]) { 7 | c = q[0]; 8 | q[0] = q[1]; 9 | q[1] = c; 10 | } 11 | YT.urls.pushState(q[0], q[1]); 12 | } else { 13 | YT.urls.pushState("UC-lHJZR3Gqxm24_Vd_AJ5Yw", "UCq-Fj5jknLsUf-MWSy4_brA"); 14 | } 15 | }, 16 | pushState: function (e, f) { 17 | if (e > f) { 18 | c = e; 19 | e = f; 20 | f = c; 21 | } 22 | history.pushState(null, null, "#!/" + e + "$$" + f); 23 | setTimeout(function () { 24 | DISQUS.reset({ 25 | reload: true, 26 | config: function () { 27 | this.page.identifier = YT.live.vs1 + "$$" + YT.live.vs2; 28 | this.page.url = baseURL + "compare/#!/" + YT.live.vs1 + "$$" + YT.live.vs2; 29 | }, 30 | }); 31 | }, 500); 32 | YT.live.setVS(e, f); 33 | }, 34 | getCurrent: function () { 35 | return baseURL + "compare/#!/" + YT.live.vs1 + "$$" + YT.live.vs2; 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /assets/js/updateManager.vs.js: -------------------------------------------------------------------------------- 1 | YT.updateManager = { 2 | prepare: function (e) { 3 | var odEl = ["#yt_subs_vs1", "#yt_subs_vs2", "#yt_diff"]; 4 | odEl.forEach(function (e) { 5 | new Odometer({ 6 | el: document.querySelector(e), 7 | value: "0", 8 | format: "(,ddd)", 9 | theme: "minimal", 10 | }); 11 | }); 12 | }, 13 | updateName: function (e, f) { 14 | $(".vs1_name").text(e); 15 | $(".vs2_name").text(f); 16 | }, 17 | updateProfile: function (e, f) { 18 | $("#yt_profile_vs1").attr("src", e); 19 | $("#yt_profile_vs2").attr("src", f); 20 | }, 21 | updateCover: function (e, f) { 22 | $("#yt_cover_vs1").attr("src", e); 23 | $("#yt_cover_vs2").attr("src", f); 24 | }, 25 | updateSubscribers: function (e, f) { 26 | $("#yt_subs_vs1").text(e); 27 | $("#yt_subs_vs2").text(f); 28 | $("#yt_diff").text(Math.abs(parseInt(e) - parseInt(f))); 29 | if (parseInt(e) - parseInt(f) > 0) { 30 | $(document.body).addClass("leading-left").removeClass("leading-right"); 31 | } else { 32 | $(document.body).addClass("leading-right").removeClass("leading-left"); 33 | } 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /assets/js/sharing.view.js: -------------------------------------------------------------------------------- 1 | YT.sharing = { 2 | youtube: function () { 3 | window.open("https://www.youtube.com/watch?v=" + YT.live.channelID); 4 | }, 5 | archive: function () { 6 | // window.open("https://promote.counts.live/youtube-view-count/" + YT.live.channelID); 7 | }, 8 | cl: function () { 9 | // window.open("https://counts.live/youtube-view-count/" + YT.live.channelID); 10 | }, 11 | twitter: function () { 12 | window.open( 13 | "https://twitter.com/intent/tweet?original_referer=" + 14 | YT.sharing.getEncodedURL() + 15 | "&ref_src=twsrc%5Etfw&text=" + 16 | YT.sharing.getText() + 17 | "&tw_p=tweetbutton&via=iakshatmittal&url=" + 18 | YT.sharing.getEncodedURL(), 19 | ); 20 | }, 21 | compare: function () { 22 | $(".super-search,.dark-bg").fadeIn(); 23 | $("#yt_searchvalue_m").focus(); 24 | }, 25 | getText: function () { 26 | return encodeURIComponent("Check out " + $("#yt_name").text() + "'s real time live view count on @YouTube!"); 27 | }, 28 | getEncodedURL: function () { 29 | return encodeURIComponent(YT.urls.getCurrent()); 30 | }, 31 | bind: function () { 32 | $("#yt_shareyt").on("click", this.youtube); 33 | $("#yt_sharetw").on("click", this.twitter); 34 | $("#yt_sharear").on("click", this.archive); 35 | $("#yt_sharear2").on("click", this.cl); 36 | $("#yt_compare").on("click", this.compare); 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /assets/js/sharing.core.js: -------------------------------------------------------------------------------- 1 | YT.sharing = { 2 | youtube: function () { 3 | window.open("https://www.youtube.com/channel/" + YT.live.channelID); 4 | }, 5 | archive: function () { 6 | // window.open("https://promote.counts.live/youtube-subscriber-count/" + YT.live.channelID); 7 | }, 8 | cl: function () { 9 | // window.open("https://counts.live/youtube-subscriber-count/" + YT.live.channelID); 10 | }, 11 | twitter: function () { 12 | window.open( 13 | "https://twitter.com/intent/tweet?original_referer=" + 14 | YT.sharing.getEncodedURL() + 15 | "&ref_src=twsrc%5Etfw&text=" + 16 | YT.sharing.getText() + 17 | "&tw_p=tweetbutton&via=iakshatmittal&url=" + 18 | YT.sharing.getEncodedURL(), 19 | ); 20 | }, 21 | compare: function () { 22 | $(".super-search,.dark-bg").fadeIn(); 23 | $("#yt_searchvalue_m").focus(); 24 | }, 25 | getText: function () { 26 | return encodeURIComponent("Check out " + $("#yt_name").text() + "'s real time subscriber count on @YouTube!"); 27 | }, 28 | getEncodedURL: function () { 29 | return encodeURIComponent(YT.urls.getCurrent()); 30 | }, 31 | bind: function () { 32 | $("#yt_shareyt").on("click", this.youtube); 33 | $("#yt_sharetw").on("click", this.twitter); 34 | $("#yt_sharear").on("click", this.compare); 35 | $("#yt_sharear2").on("click", this.cl); 36 | $("#yt_compare").on("click", this.compare); 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /assets/js/updateManager.core.js: -------------------------------------------------------------------------------- 1 | YT.updateManager = { 2 | prepare: function (e) { 3 | var odEl = ["#yt_subs", "#yt_views", "#yt_videos"]; 4 | odEl.forEach(function (e) { 5 | new Odometer({ 6 | el: document.querySelector(e), 7 | value: "0", 8 | format: "(,ddd)", 9 | theme: "minimal", 10 | }); 11 | }); 12 | }, 13 | updateName: function (e) { 14 | $(".yt_name").text(e); 15 | }, 16 | updateProfile: function (e) { 17 | $("#yt_profile").attr("src", e); 18 | }, 19 | updateCover: function (e) { 20 | $("#yt_cover").attr("src", e); 21 | }, 22 | updateSubscribers: function (e) { 23 | $("#yt_subs").text(e); 24 | }, 25 | updateViews: function (e) { 26 | $("#yt_views").text(e); 27 | }, 28 | updateVideos: function (e) { 29 | $("#yt_videos").text(e); 30 | }, 31 | updateChannelID: function (e) { 32 | YT.live.channelID = e; 33 | $("#yt_shareurl").val(YT.urls.getCurrent()); 34 | $("#yt_embed_small").val( 35 | '