podcast-dl 11.5.0 → 11.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/ffmpeg.js CHANGED
@@ -1,105 +1,109 @@
1
- import dayjs from "dayjs";
2
- import fs from "fs";
3
- import { execWithPromise } from "./exec.js";
4
- import { LOG_LEVELS, logMessage } from "./logger.js";
5
- import { escapeArgForShell, isWin } from "./util.js";
6
-
7
- export const runFfmpeg = async ({
8
- feed,
9
- item,
10
- itemIndex,
11
- outputPath,
12
- episodeImageOutputPath,
13
- bitrate,
14
- mono,
15
- addMp3Metadata,
16
- ext,
17
- }) => {
18
- if (!fs.existsSync(outputPath)) {
19
- return;
20
- }
21
-
22
- const shouldEmbedImage = addMp3Metadata && episodeImageOutputPath;
23
- let command = `ffmpeg -loglevel quiet -i ${escapeArgForShell(outputPath)}`;
24
-
25
- if (shouldEmbedImage) {
26
- command += ` -i ${escapeArgForShell(episodeImageOutputPath)}`;
27
- }
28
-
29
- if (bitrate) {
30
- command += ` -b:a ${bitrate}`;
31
- }
32
-
33
- if (mono) {
34
- command += " -ac 1";
35
- }
36
-
37
- if (addMp3Metadata) {
38
- const album = feed.title || "";
39
- const artist = item.itunes?.author || item.author || "";
40
- const title = item.title || "";
41
- const subtitle = item.itunes?.subtitle || "";
42
- const comment = item.contentSnippet || item.content || "";
43
- const disc = item.itunes?.season || "";
44
- const track = item.itunes?.episode || `${feed.items.length - itemIndex}`;
45
- const episodeType = item.itunes?.episodeType || "";
46
- const date = item.pubDate
47
- ? dayjs(new Date(item.pubDate)).format("YYYY-MM-DD")
48
- : "";
49
-
50
- const metaKeysToValues = {
51
- album,
52
- artist,
53
- album_artist: artist,
54
- title,
55
- disc,
56
- track,
57
- "episode-type": episodeType,
58
- date,
59
- };
60
-
61
- if (!isWin) {
62
- // Due to limited escape options, these metadata fields often break in Windows
63
- metaKeysToValues.comment = comment;
64
- metaKeysToValues.subtitle = subtitle
65
- }
66
-
67
- const metadataString = Object.keys(metaKeysToValues)
68
- .map((key) => {
69
- if (!metaKeysToValues[key]) {
70
- return null;
71
- }
72
-
73
- const argValue = escapeArgForShell(metaKeysToValues[key]);
74
-
75
- return argValue ? `-metadata ${key}=${argValue}` : null;
76
- })
77
- .filter((segment) => !!segment)
78
- .join(" ");
79
-
80
- command += ` -map_metadata 0 ${metadataString} -codec copy`;
81
- }
82
-
83
- if (shouldEmbedImage) {
84
- command += ` -map 0 -map 1`;
85
- } else {
86
- command += ` -map 0`;
87
- }
88
-
89
- const tmpMp3Path = `${outputPath}.tmp${ext}`;
90
- command += ` ${escapeArgForShell(tmpMp3Path)}`;
91
- logMessage("Running command: " + command, LOG_LEVELS.debug);
92
-
93
- try {
94
- await execWithPromise(command, { stdio: "ignore" });
95
- } catch (error) {
96
- if (fs.existsSync(tmpMp3Path)) {
97
- fs.unlinkSync(tmpMp3Path);
98
- }
99
-
100
- throw error;
101
- }
102
-
103
- fs.unlinkSync(outputPath);
104
- fs.renameSync(tmpMp3Path, outputPath);
105
- };
1
+ import dayjs from "dayjs";
2
+ import fs from "fs";
3
+ import { execWithPromise } from "./exec.js";
4
+ import { LOG_LEVELS, logMessage } from "./logger.js";
5
+ import { escapeArgForShell, isWin } from "./util.js";
6
+
7
+ export const runFfmpeg = async ({
8
+ feed,
9
+ item,
10
+ itemIndex,
11
+ outputPath,
12
+ episodeImageOutputPath,
13
+ bitrate,
14
+ mono,
15
+ addMp3Metadata,
16
+ ext,
17
+ }) => {
18
+ if (!fs.existsSync(outputPath)) {
19
+ return;
20
+ }
21
+
22
+ const shouldEmbedImage = addMp3Metadata && episodeImageOutputPath;
23
+ let command = `ffmpeg -loglevel quiet -i ${escapeArgForShell(outputPath)}`;
24
+
25
+ if (shouldEmbedImage) {
26
+ command += ` -i ${escapeArgForShell(episodeImageOutputPath)}`;
27
+ }
28
+
29
+ if (bitrate) {
30
+ command += ` -b:a ${bitrate}`;
31
+ }
32
+
33
+ if (mono) {
34
+ command += " -ac 1";
35
+ }
36
+
37
+ if (addMp3Metadata) {
38
+ const album = feed.title || "";
39
+ const artist = item.itunes?.author || item.author || "";
40
+ const title = item.title || "";
41
+ const subtitle = item.itunes?.subtitle || "";
42
+ const comment = item.contentSnippet || item.content || "";
43
+ const disc = item.itunes?.season || "";
44
+ const track = item.itunes?.episode || `${feed.items.length - itemIndex}`;
45
+ const episodeType = item.itunes?.episodeType || "";
46
+ const date = item.pubDate
47
+ ? dayjs(new Date(item.pubDate)).format("YYYY-MM-DD")
48
+ : "";
49
+
50
+ const metaKeysToValues = {
51
+ album,
52
+ artist,
53
+ album_artist: artist,
54
+ title,
55
+ disc,
56
+ track,
57
+ "episode-type": episodeType,
58
+ date,
59
+ };
60
+
61
+ if (!isWin) {
62
+ // Due to limited escape options, these metadata fields often break in Windows
63
+ metaKeysToValues.comment = comment;
64
+ metaKeysToValues.subtitle = subtitle;
65
+ }
66
+
67
+ const metadataString = Object.keys(metaKeysToValues)
68
+ .map((key) => {
69
+ if (!metaKeysToValues[key]) {
70
+ return null;
71
+ }
72
+
73
+ const argValue = escapeArgForShell(metaKeysToValues[key]);
74
+
75
+ return argValue ? `-metadata ${key}=${argValue}` : null;
76
+ })
77
+ .filter((segment) => !!segment)
78
+ .join(" ");
79
+
80
+ command += ` -map_metadata 0 ${metadataString}`;
81
+
82
+ if (!bitrate && !mono) {
83
+ command += ` -codec copy`;
84
+ }
85
+ }
86
+
87
+ if (shouldEmbedImage) {
88
+ command += ` -map 0 -map 1`;
89
+ } else {
90
+ command += ` -map 0`;
91
+ }
92
+
93
+ const tmpMp3Path = `${outputPath}.tmp${ext}`;
94
+ command += ` ${escapeArgForShell(tmpMp3Path)}`;
95
+ logMessage("Running command: " + command, LOG_LEVELS.debug);
96
+
97
+ try {
98
+ await execWithPromise(command, { stdio: "ignore" });
99
+ } catch (error) {
100
+ if (fs.existsSync(tmpMp3Path)) {
101
+ fs.unlinkSync(tmpMp3Path);
102
+ }
103
+
104
+ throw error;
105
+ }
106
+
107
+ fs.unlinkSync(outputPath);
108
+ fs.renameSync(tmpMp3Path, outputPath);
109
+ };
package/bin/util.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import rssParser from "rss-parser";
3
+ import rssParser from "../lib/rss-parser/parser.js";
4
4
  import { logErrorAndExit, logMessage } from "./logger.js";
5
5
 
6
6
  export const isWin = process.platform === "win32";
@@ -10,9 +10,6 @@ export const defaultRssParserConfig = {
10
10
  headers: {
11
11
  Accept: "*/*",
12
12
  },
13
- customFields: {
14
- item: [["podcast:transcript", "podcastTranscripts", { keepArray: true }]],
15
- },
16
13
  };
17
14
 
18
15
  /*
package/bin/validate.js CHANGED
@@ -32,8 +32,10 @@ export const createParseNumber = ({ min, max, name, required = true }) => {
32
32
  };
33
33
  };
34
34
 
35
- export const hasFfmpeg = () => {
35
+ export const hasFfmpeg = (value) => {
36
36
  if (!commandExistsSync("ffmpeg")) {
37
37
  logErrorAndExit('option specified requires "ffmpeg" be available');
38
38
  }
39
+
40
+ return value;
39
41
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "podcast-dl",
3
- "version": "11.5.0",
3
+ "version": "11.5.1",
4
4
  "description": "A CLI for downloading podcasts.",
5
5
  "type": "module",
6
6
  "bin": "./bin/bin.js",
@@ -57,7 +57,8 @@
57
57
  "got": "^11.0.2",
58
58
  "p-limit": "^4.0.0",
59
59
  "pluralize": "^8.0.0",
60
- "rss-parser": "^3.12.0",
60
+ "entities": "^2.0.3",
61
+ "xml2js": "^0.5.0",
61
62
  "throttle-debounce": "^3.0.1"
62
63
  }
63
64
  }