From f69b67e094d5750e72dca13fe7dd42ff74a9acac Mon Sep 17 00:00:00 2001 From: Aleksandar Matevski Date: Tue, 12 Apr 2022 00:48:15 +0200 Subject: [PATCH 1/6] Add environment variable 'IS_EXPLICIT' IS_EXPLICIT will specify if podcast to be published on anchor.fm is clean or explicit --- index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/index.js b/index.js index 0b9494f7..8bcb0167 100644 --- a/index.js +++ b/index.js @@ -21,6 +21,9 @@ const outputFile = 'episode.mp3'; const draftMode = GetEnvironmentVar('SAVE_AS_DRAFT', 'false') const actionText = draftMode == 'true' ? 'Save as draft' : 'Publish now' +const isExplicit = GetEnvironmentVar('IS_EXPLICIT', 'false') +const selectorForExplicitContentLabel = isExplicit == 'true' ? 'label[for="podcastEpisodeIsExplicit-true"]' : 'label[for="podcastEpisodeIsExplicit-false"]' + // Allow fine tunning of the converted audio file // Example: "ffmpeg:-ac 1" for mono mp3 const postprocessorArgs = GetEnvironmentVar('POSTPROCESSOR_ARGS', "") @@ -115,6 +118,11 @@ exec('sudo curl -k -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/ await page.waitForSelector('div[role="textbox"]', { visible: true }); await page.type('div[role="textbox"]', episode.description); + console.log("-- Selecting content type") + await page.waitForSelector(selectorForExplicitContentLabel, { visible: true}) + const contentTypeLabel = await page.$(selectorForExplicitContentLabel) + await contentTypeLabel.click() + console.log("-- Publishing"); const [button] = await page.$x(`//button[text()="${actionText}"]`); From 98773e476d86683ce24c245381303c76c7683cde Mon Sep 17 00:00:00 2001 From: Aleksandar Matevski Date: Wed, 13 Apr 2022 19:13:22 +0200 Subject: [PATCH 2/6] Upload episode art from youtube thumbnail --- index.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 8bcb0167..587a0f9b 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -const { exec } = require('child_process'); +const { exec, execSync } = require('child_process'); const fs = require('fs'); function GetEnvironmentVar(varname, defaultvalue) { @@ -13,6 +13,7 @@ const email = process.env.ANCHOR_EMAIL; const password = process.env.ANCHOR_PASSWORD; const UPLOAD_TIMEOUT = process.env.UPLOAD_TIMEOUT || 60 * 5 * 1000; +const THUMBNAIL_FORMAT = "jpg"; const YT_URL = 'https://www.youtube.com/watch?v='; const pathToEpisodeJSON = GetEnvironmentVar('EPISODE_PATH','.') + '/episode.json'; const outputFile = 'episode.mp3'; @@ -48,6 +49,8 @@ exec('sudo curl -k -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/ const YT_ID = epConfJSON.id; console.log(`Processing: ${YT_ID}`); const url = YT_URL + YT_ID; + const thumbnailOutputFileTemplate = `thumbnail.%(ext)s` + const thumbnailOutputFile = `thumbnail.${THUMBNAIL_FORMAT}` youtubedl.getInfo(url, function (err, info) { if (err) throw err; @@ -57,6 +60,11 @@ exec('sudo curl -k -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/ console.log(`title: ${epConfJSON.title}`) console.log(`description: ${epConfJSON.description}`) + const youtubeDlThumbnailCommand = `youtube-dl -o "${thumbnailOutputFileTemplate}" --skip-download --write-thumbnail --convert-thumbnails ${THUMBNAIL_FORMAT} ${url}` + console.log(`Thumbnail download command: ${youtubeDlThumbnailCommand}`) + const thumbnailDownloadStdout = execSync(youtubeDlThumbnailCommand) + console.log(`stdout: ${thumbnailDownloadStdout}`) + const youtubeDlCommand = `youtube-dl -o ${outputFile} -f bestaudio -x --force-overwrites --audio-format mp3 ${postprocessorArgsCmd} ${url}`; console.log(`Download command: ${youtubeDlCommand}`) @@ -123,6 +131,17 @@ exec('sudo curl -k -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/ const contentTypeLabel = await page.$(selectorForExplicitContentLabel) await contentTypeLabel.click() + console.log("-- Uploading episode art") + await page.waitForSelector('input[type=file][accept="image/*"]'); + const inputEpisodeArt = await page.$('input[type=file][accept="image/*"]'); + await inputEpisodeArt.uploadFile(thumbnailOutputFile); + + console.log("-- Saving uploaded episode art") + await page.waitForXPath('//button/div[text()="Save"]') + const [saveEpisodeArtButton] = await page.$x('//button/div[text()="Save"]') + await saveEpisodeArtButton.click() + await page.waitForXPath('//div[@aria-label="image uploader"]', { hidden: true, timeout: UPLOAD_TIMEOUT}) + console.log("-- Publishing"); const [button] = await page.$x(`//button[text()="${actionText}"]`); From 7f739ed080325ceba6d1823e2285b46ccec3e961 Mon Sep 17 00:00:00 2001 From: Aleksandar Matevski Date: Fri, 15 Apr 2022 23:08:38 +0200 Subject: [PATCH 3/6] Fix save as draft and publish button --- index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 587a0f9b..f330e085 100644 --- a/index.js +++ b/index.js @@ -18,9 +18,8 @@ const YT_URL = 'https://www.youtube.com/watch?v='; const pathToEpisodeJSON = GetEnvironmentVar('EPISODE_PATH','.') + '/episode.json'; const outputFile = 'episode.mp3'; -// Just save as draft, to allow approval flow. const draftMode = GetEnvironmentVar('SAVE_AS_DRAFT', 'false') -const actionText = draftMode == 'true' ? 'Save as draft' : 'Publish now' +const saveDraftOrPublishButtonXPath = draftMode == 'true' ? '//button[text()="Save as draft"]' : '//button/div[text()="Publish now"]' const isExplicit = GetEnvironmentVar('IS_EXPLICIT', 'false') const selectorForExplicitContentLabel = isExplicit == 'true' ? 'label[for="podcastEpisodeIsExplicit-true"]' : 'label[for="podcastEpisodeIsExplicit-false"]' @@ -143,7 +142,7 @@ exec('sudo curl -k -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/ await page.waitForXPath('//div[@aria-label="image uploader"]', { hidden: true, timeout: UPLOAD_TIMEOUT}) console.log("-- Publishing"); - const [button] = await page.$x(`//button[text()="${actionText}"]`); + const [button] = await page.$x(saveDraftOrPublishButtonXPath); // If no button is found using label, try using css path if (button) { From ef0deeb9205b8c88a06f44bbde97c2dffe8d5b13 Mon Sep 17 00:00:00 2001 From: Abe Date: Tue, 10 May 2022 09:59:53 -0400 Subject: [PATCH 4/6] Add LOAD_THUMBNAIL insturctions --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 7b94c64f..a3b2c465 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,14 @@ env: POSTPROCESSOR_ARGS: "ffmpeg:-ac 1" ``` +## Thumbnail Mode + +By seting the `LOAD_THUMBNAIL`, the new episode will include the video thumbnail as the episode art. +```yaml +env: + LOAD_THUMBNAIL: true +``` + # Credits [@thejoin](https://github.com/thejoin95) & [@wabri](https://github.com/wabri) From e00e09fce071cde033e8fba3d80802918c2e9a40 Mon Sep 17 00:00:00 2001 From: Abe Date: Mon, 9 May 2022 12:14:03 -0400 Subject: [PATCH 5/6] create LOAD_THUMBNAIL env variable --- index.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/index.js b/index.js index f330e085..b16ff8ea 100644 --- a/index.js +++ b/index.js @@ -21,6 +21,8 @@ const outputFile = 'episode.mp3'; const draftMode = GetEnvironmentVar('SAVE_AS_DRAFT', 'false') const saveDraftOrPublishButtonXPath = draftMode == 'true' ? '//button[text()="Save as draft"]' : '//button/div[text()="Publish now"]' +const thumbnailMode = GetEnvironmentVar('LOAD_THUMBNAIL', 'false') + const isExplicit = GetEnvironmentVar('IS_EXPLICIT', 'false') const selectorForExplicitContentLabel = isExplicit == 'true' ? 'label[for="podcastEpisodeIsExplicit-true"]' : 'label[for="podcastEpisodeIsExplicit-false"]' @@ -130,16 +132,18 @@ exec('sudo curl -k -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/ const contentTypeLabel = await page.$(selectorForExplicitContentLabel) await contentTypeLabel.click() - console.log("-- Uploading episode art") - await page.waitForSelector('input[type=file][accept="image/*"]'); - const inputEpisodeArt = await page.$('input[type=file][accept="image/*"]'); - await inputEpisodeArt.uploadFile(thumbnailOutputFile); - - console.log("-- Saving uploaded episode art") - await page.waitForXPath('//button/div[text()="Save"]') - const [saveEpisodeArtButton] = await page.$x('//button/div[text()="Save"]') - await saveEpisodeArtButton.click() - await page.waitForXPath('//div[@aria-label="image uploader"]', { hidden: true, timeout: UPLOAD_TIMEOUT}) + if (thumbnailMode !== 'false') { + console.log("-- Uploading episode art") + await page.waitForSelector('input[type=file][accept="image/*"]'); + const inputEpisodeArt = await page.$('input[type=file][accept="image/*"]'); + await inputEpisodeArt.uploadFile(thumbnailOutputFile); + + console.log("-- Saving uploaded episode art") + await page.waitForXPath('//button/div[text()="Save"]') + const [saveEpisodeArtButton] = await page.$x('//button/div[text()="Save"]') + await saveEpisodeArtButton.click() + await page.waitForXPath('//div[@aria-label="image uploader"]', { hidden: true, timeout: UPLOAD_TIMEOUT}) + } console.log("-- Publishing"); const [button] = await page.$x(saveDraftOrPublishButtonXPath); From c44b8dfd82570f1fd69605f68bf7eb4eeddf1812 Mon Sep 17 00:00:00 2001 From: Abe Date: Wed, 11 May 2022 13:48:42 -0400 Subject: [PATCH 6/6] add IS_EXPLICIT instructions --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a3b2c465..0ad896a4 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,17 @@ env: POSTPROCESSOR_ARGS: "ffmpeg:-ac 1" ``` +## Explicit Mode + +By setting the `IS_EXPLICIT`, the new episode will be marked as explicit. +```yaml +env: + IS_EXPLICIT: true +``` + ## Thumbnail Mode -By seting the `LOAD_THUMBNAIL`, the new episode will include the video thumbnail as the episode art. +By setting the `LOAD_THUMBNAIL`, the new episode will include the video thumbnail as the episode art. ```yaml env: LOAD_THUMBNAIL: true