From 0557f82eedac0ce17b63429f25bfd77994041f90 Mon Sep 17 00:00:00 2001 From: Elanis Date: Sat, 21 Aug 2021 12:39:07 +0200 Subject: [PATCH] Get a playlist content & duration Soon, we'll be able to display data ! --- .gitignore | 1 + main.js | 95 +++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 31 ++++++++++++++++ package.json | 14 +++++++ 4 files changed, 141 insertions(+) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/main.js b/main.js index e69de29..90746fe 100644 --- a/main.js +++ b/main.js @@ -0,0 +1,95 @@ +const fetch = require('node-fetch'); + +const fs = require('fs'); + +const PLAYLIST_ID = ''; +const API_KEY = ''; + +async function getVideoData(videoId) { + const res = await fetch( + `https://www.googleapis.com/youtube/v3/videos?id=${videoId}&key=${API_KEY}` + ); + + return await res.json(); +} + +async function getVideosData(videosId) { + const res = await fetch( + `https://youtube.googleapis.com/youtube/v3/videos?part=snippet%2CcontentDetails%2Cstatistics&id=${videosId.join(',')}&key=${API_KEY}` + ); + + return await res.json(); +} + +const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/; +function parseISO8601Duration(iso8601Duration) { + const matches = iso8601Duration.match(iso8601DurationRegex); + + return { + sign: matches[1] === undefined ? '+' : '-', + years: matches[2] === undefined ? 0 : parseInt(matches[2]), + months: matches[3] === undefined ? 0 : parseInt(matches[3]), + weeks: matches[4] === undefined ? 0 : parseInt(matches[4]), + days: matches[5] === undefined ? 0 : parseInt(matches[5]), + hours: matches[6] === undefined ? 0 : parseInt(matches[6]), + minutes: matches[7] === undefined ? 0 : parseInt(matches[7]), + seconds: matches[8] === undefined ? 0 : parseInt(matches[8]) + }; +} + +async function getPlayListData(playlistId) { + const finalResult = []; + let obj = {}; + do { + let res; + + if(obj.nextPageToken) { + res = await fetch( + `https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=${playlistId}&key=${API_KEY}&pageToken=${obj.nextPageToken}` + ); + } else { + res = await fetch( + `https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=${playlistId}&key=${API_KEY}` + ); + } + + obj = await res.json(); + const videos = await getVideosData(obj.items.map((elt) => elt.snippet.resourceId.videoId)); + finalResult.push(...obj.items.map((elt) => { + elt.videoData = videos.items.filter((video) => + video.id === elt.snippet.resourceId.videoId + )[0]; + + return elt; + })); + } while(obj.nextPageToken); + + return finalResult; +} + +(async() => { + const playlistData = await getPlayListData(PLAYLIST_ID, 0); + + console.log('Video count: ', playlistData.length); + const totalDuration = playlistData.reduce((acc, item) => { + const duration = parseISO8601Duration(item.videoData.contentDetails.duration); + + acc.hours += duration.days * 24; + acc.hours += duration.hours; + acc.minutes += duration.minutes; + acc.seconds += duration.seconds; + + while(acc.seconds > 60) { + acc.seconds -= 60; + acc.minutes++; + } + + while(acc.minutes > 60) { + acc.minutes -= 60; + acc.hours++; + } + + return acc; + }, { hours: 0, minutes: 0, seconds: 0 }); + console.log('Total duration: ', totalDuration.hours.toString().padStart(2, '0') + ':' + totalDuration.minutes.toString().padStart(2, '0') + ':' + totalDuration.seconds.toString().padStart(2, '0')); +})(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..01a13ea --- /dev/null +++ b/package-lock.json @@ -0,0 +1,31 @@ +{ + "name": "lumen-module-youtube", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "lumen-module-youtube", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "node-fetch": "^2.6.1" + } + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + } + }, + "dependencies": { + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9467d00 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "lumen-module-youtube", + "version": "1.0.0", + "description": "Youtube Module", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "node-fetch": "^2.6.1" + } +}