-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a5a4c2e
commit 1bf22ab
Showing
15 changed files
with
241 additions
and
207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
.yarn/* | ||
!.yarn/patches | ||
!.yarn/plugins | ||
!.yarn/releases | ||
!.yarn/sdks | ||
!.yarn/versions | ||
!.yarn/cache | ||
.env | ||
dist/ | ||
node_modules/ | ||
output/ |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,36 @@ | ||
{ | ||
"name": "algorave-downloader", | ||
"packageManager": "[email protected]", | ||
"private": true, | ||
"volta": { | ||
"node": "18.12.1", | ||
"yarn": "3.3.0" | ||
}, | ||
"devDependencies": { | ||
"@sapphire/ts-config": "^3.3.4", | ||
"@types/cors": "^2.8.12", | ||
"@types/express": "^4.17.14", | ||
"@types/fluent-ffmpeg": "^2.1.20", | ||
"@types/node": "^18.11.9", | ||
"@types/node-cron": "^3.0.6", | ||
"typescript": "^4.9.3" | ||
}, | ||
"dependencies": { | ||
"@ffmpeg-installer/ffmpeg": "^1.1.0", | ||
"@ffprobe-installer/ffprobe": "^1.4.1", | ||
"@sapphire/fetch": "^2.4.1", | ||
"cors": "^2.8.5", | ||
"dotenv": "^16.0.3", | ||
"express": "^4.18.2", | ||
"fluent-ffmpeg": "^2.1.2", | ||
"node-cron": "^3.0.2" | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"start": "node dist/index.js", | ||
"initDownload": "node dist/scripts/initDownload" | ||
} | ||
"name": "algorave-downloader", | ||
"packageManager": "[email protected]", | ||
"private": true, | ||
"volta": { | ||
"node": "18.12.1", | ||
"yarn": "3.3.0" | ||
}, | ||
"devDependencies": { | ||
"@sapphire/prettier-config": "^1.4.4", | ||
"@sapphire/ts-config": "^3.3.4", | ||
"@types/cors": "^2.8.12", | ||
"@types/express": "^4.17.14", | ||
"@types/fluent-ffmpeg": "^2.1.20", | ||
"@types/node": "^18.11.9", | ||
"@types/node-cron": "^3.0.6", | ||
"prettier": "^2.7.1", | ||
"typescript": "^4.9.3" | ||
}, | ||
"dependencies": { | ||
"@ffmpeg-installer/ffmpeg": "^1.1.0", | ||
"@ffprobe-installer/ffprobe": "^1.4.1", | ||
"@sapphire/fetch": "^2.4.1", | ||
"cors": "^2.8.5", | ||
"dotenv": "^16.0.3", | ||
"express": "^4.18.2", | ||
"fluent-ffmpeg": "^2.1.2", | ||
"node-cron": "^3.0.2" | ||
}, | ||
"scripts": { | ||
"build": "tsc", | ||
"start": "node dist/index.js", | ||
"initDownload": "node dist/scripts/initDownload" | ||
}, | ||
"prettier": "@sapphire/prettier-config" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,37 @@ | ||
<html lang="en"> | ||
<head> | ||
<title>UTC-Sheffield Algorave | Audio</title> | ||
</head> | ||
<body> | ||
<noscript> | ||
<p>Sorry, this page requires JavaScript to work</p> | ||
</noscript> | ||
<h1>UTC-Sheffield Algorave | Audio</h1> | ||
<p> | ||
Audio only recordings of our <a href="https://youtube.com/@alograve-UTCsheffield">live coding streams</a>. | ||
</p> | ||
<div id="audio-container"> | ||
</div> | ||
<script> | ||
async function main() { | ||
const res = await fetch(`${location.protocol}//${location.host}/tracks`) | ||
const tracks = await res.json() | ||
var container = document.getElementById("audio-container"); | ||
tracks.tracks.forEach((track) => { | ||
// add container | ||
const trackContainer = document.createElement("div"); | ||
// add title element | ||
const title = document.createElement("h2"); | ||
const str = track.replace(`Audio-`, ``).replace(`.mp3`, ``); | ||
title.appendChild(document.createTextNode(str)); | ||
trackContainer.appendChild(title); | ||
// add audio element | ||
const audio = document.createElement("audio"); | ||
audio.setAttribute("controls", ""); | ||
audio.setAttribute("src", `/tracks/${track.replace(`.mp3`, ``)}`); | ||
trackContainer.appendChild(audio); | ||
<head> | ||
<title>UTC-Sheffield Algorave | Audio</title> | ||
</head> | ||
<body> | ||
<noscript> | ||
<p>Sorry, this page requires JavaScript to work</p> | ||
</noscript> | ||
<h1>UTC-Sheffield Algorave | Audio</h1> | ||
<p>Audio only recordings of our <a href="https://youtube.com/@alograve-UTCsheffield">live coding streams</a>.</p> | ||
<div id="audio-container"></div> | ||
<script> | ||
async function main() { | ||
const res = await fetch(`${location.protocol}//${location.host}/tracks`); | ||
const tracks = await res.json(); | ||
var container = document.getElementById('audio-container'); | ||
tracks.tracks.forEach((track) => { | ||
// add container | ||
const trackContainer = document.createElement('div'); | ||
// add title element | ||
const title = document.createElement('h2'); | ||
const str = track.replace(`Audio-`, ``).replace(`.mp3`, ``); | ||
title.appendChild(document.createTextNode(str)); | ||
trackContainer.appendChild(title); | ||
// add audio element | ||
const audio = document.createElement('audio'); | ||
audio.setAttribute('controls', ''); | ||
audio.setAttribute('src', `/tracks/${track.replace(`.mp3`, ``)}`); | ||
trackContainer.appendChild(audio); | ||
|
||
container.appendChild(trackContainer); | ||
}); | ||
} | ||
main(); | ||
</script> | ||
</body> | ||
</html> | ||
container.appendChild(trackContainer); | ||
}); | ||
} | ||
main(); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
{ | ||
"$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
"extends": [ | ||
"config:base" | ||
], | ||
"automerge": true | ||
"$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
"extends": ["config:base"], | ||
"automerge": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,17 @@ | ||
import { fetch } from "@sapphire/fetch"; | ||
import type { YTVideoList } from "./types/youtubeApi.js"; | ||
import processDownload from "./lib/download/processDownload.js"; | ||
import { fetch } from '@sapphire/fetch'; | ||
import type { YTVideoList } from './types/youtubeApi.js'; | ||
import processDownload from './lib/download/processDownload.js'; | ||
// get list of a video sorted by date | ||
function getVideoList() { | ||
return fetch<YTVideoList>(`https://www.googleapis.com/youtube/v3/search?key=${String(process.env.YOUTUBE_API_KEY)}&channelId=${String(process.env.YOUTUBE_CHANNEL_ID)}&part=snippet,id&order=date&maxResults=20`) | ||
return fetch<YTVideoList>( | ||
`https://www.googleapis.com/youtube/v3/search?key=${String(process.env.YOUTUBE_API_KEY)}&channelId=${String( | ||
process.env.YOUTUBE_CHANNEL_ID | ||
)}&part=snippet,id&order=date&maxResults=20` | ||
); | ||
} | ||
export default function downloadModule() { | ||
getVideoList().then((res) => { | ||
console.log(`Fetched Video ${res.items[0].id.videoId}`); | ||
processDownload(res.items[0].id.videoId) | ||
}); | ||
} | ||
getVideoList().then((res) => { | ||
console.log(`Fetched Video ${res.items[0].id.videoId}`); | ||
processDownload(res.items[0].id.videoId); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import "dotenv/config" | ||
import "./webserverModule.js" | ||
import { schedule } from "node-cron"; | ||
import downloadModule from "./downloadModule.js" | ||
import 'dotenv/config'; | ||
import './webserverModule.js'; | ||
import { schedule } from 'node-cron'; | ||
import downloadModule from './downloadModule.js'; | ||
|
||
schedule("0 5 * * TUE", downloadModule); | ||
schedule('0 5 * * TUE', downloadModule); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,42 @@ | ||
import {spawn} from "node:child_process"; | ||
import { existsSync } from "node:fs"; | ||
import ffmpeg from "./ffmpeg.js"; | ||
import { spawn } from 'node:child_process'; | ||
import { existsSync } from 'node:fs'; | ||
import ffmpeg from './ffmpeg.js'; | ||
export default function processDownload(vidID: string) { | ||
try { | ||
if (!existsSync(`${process.cwd()}/output/Video-${vidID}.mp4`)) { | ||
console.log("Downloading Video") | ||
const ytdl = spawn("youtube-dl", [`-o`, `${process.cwd()}/output/Video-%(id)s.%(ext)s`, `https://www.youtube.com/watch?v=${vidID}`]); | ||
ytdl.stdout.on("data", (data) => { | ||
console.log(`[YTDL] [${vidID}] stdout: ${data}`); | ||
}); | ||
ytdl.stderr.on("data", (data) => { | ||
console.error(`[YTDL] [${vidID}] stderr: ${data}`); | ||
}); | ||
ytdl.on('close', (code) => { | ||
console.log(`[YTDL] [${vidID}] child process exited with code ${code}`); | ||
if (code === 0) { | ||
stripVideo(vidID); | ||
} else { | ||
return | ||
} | ||
}); | ||
} else { | ||
console.log("the Video is already downloaded"); | ||
stripVideo(vidID); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
try { | ||
if (!existsSync(`${process.cwd()}/output/Video-${vidID}.mp4`)) { | ||
console.log('Downloading Video'); | ||
const ytdl = spawn('youtube-dl', [`-o`, `${process.cwd()}/output/Video-%(id)s.%(ext)s`, `https://www.youtube.com/watch?v=${vidID}`]); | ||
ytdl.stdout.on('data', (data) => { | ||
console.log(`[YTDL] [${vidID}] stdout: ${data}`); | ||
}); | ||
ytdl.stderr.on('data', (data) => { | ||
console.error(`[YTDL] [${vidID}] stderr: ${data}`); | ||
}); | ||
ytdl.on('close', (code) => { | ||
console.log(`[YTDL] [${vidID}] child process exited with code ${code}`); | ||
if (code === 0) { | ||
stripVideo(vidID); | ||
} else { | ||
return; | ||
} | ||
}); | ||
} else { | ||
console.log('the Video is already downloaded'); | ||
stripVideo(vidID); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
function stripVideo(vidID: string) { | ||
try { | ||
if (!existsSync(`${process.cwd()}/output/Audio-${vidID}.mp3`)) { | ||
console.log("Stripping Video") | ||
ffmpeg() | ||
.input(`${process.cwd()}/output/Video-${vidID}.mp4`) | ||
.save(`${process.cwd()}/output/Audio-${vidID}.mp3`) | ||
} else { | ||
console.log("the Video is already stripped"); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} | ||
try { | ||
if (!existsSync(`${process.cwd()}/output/Audio-${vidID}.mp3`)) { | ||
console.log('Stripping Video'); | ||
ffmpeg().input(`${process.cwd()}/output/Video-${vidID}.mp4`).save(`${process.cwd()}/output/Audio-${vidID}.mp3`); | ||
} else { | ||
console.log('the Video is already stripped'); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
import fs from "fs"; | ||
import fs from 'fs'; | ||
|
||
export default function readOutputDir() { | ||
const arr = []; | ||
const files = fs.readdirSync(`${process.cwd()}/output`).filter(file => file.endsWith(".mp3")); | ||
for (const file of files) { | ||
arr.push(file); | ||
} | ||
return arr; | ||
} | ||
const arr = []; | ||
const files = fs.readdirSync(`${process.cwd()}/output`).filter((file) => file.endsWith('.mp3')); | ||
for (const file of files) { | ||
arr.push(file); | ||
} | ||
return arr; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,19 @@ | ||
import { fetch } from "@sapphire/fetch"; | ||
import type { YTVideoList } from "./../types/youtubeApi.js"; | ||
import processDownload from "./../lib/download/processDownload.js"; | ||
import "dotenv/config"; | ||
import { fetch } from '@sapphire/fetch'; | ||
import type { YTVideoList } from './../types/youtubeApi.js'; | ||
import processDownload from './../lib/download/processDownload.js'; | ||
import 'dotenv/config'; | ||
// get list of a video sorted by date | ||
function getVideoList() { | ||
return fetch<YTVideoList>(`https://www.googleapis.com/youtube/v3/search?key=${String(process.env.YOUTUBE_API_KEY)}&channelId=${String(process.env.YOUTUBE_CHANNEL_ID)}&part=snippet,id&order=date&maxResults=20`) | ||
return fetch<YTVideoList>( | ||
`https://www.googleapis.com/youtube/v3/search?key=${String(process.env.YOUTUBE_API_KEY)}&channelId=${String( | ||
process.env.YOUTUBE_CHANNEL_ID | ||
)}&part=snippet,id&order=date&maxResults=20` | ||
); | ||
} | ||
getVideoList().then((res) => { | ||
res.items.forEach((item) => { | ||
if (!item.id) return; | ||
console.log(`Fetched Video ${item.id.videoId}`); | ||
processDownload(item.id.videoId) | ||
}) | ||
}); | ||
res.items.forEach((item) => { | ||
if (!item.id) return; | ||
console.log(`Fetched Video ${item.id.videoId}`); | ||
processDownload(item.id.videoId); | ||
}); | ||
}); |
Oops, something went wrong.