Add a --timestamps-are-durations flag
Diff
index.js | 16 ++++++++++++++++
src/parser.js | 11 ++++++++---
test/parser_test.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 7 deletions(-)
@@ -1,9 +1,10 @@
#!/usr/bin/env node
import ytdl from 'ytdl-core';
import getArtistTitle from 'get-artist-title'
import {parse} from './src/parser.js'
import {generate} from './src/cue.js'
import minimist from 'minimist'
import exit from 'process'
let argv = minimist(process.argv.slice(2), {
string: 'audio-file'
@@ -23,7 +24,11 @@
where $VIDEOTITLE is the title of the YouTube video.
--timestamps-only Do not try to parse the timestamps as track durations
--timestamps-are-durations Parse timestamps as durations
The above 2 are only needed to force behaviour in very specific edge cases, they should
not be required for most files.
Examples
$ youtube-cue --audio-file audio.m4a "https://www.youtube.com/watch?v=THzUassmQwE"
"T A Y L O R S W I F T – Folklore [Full album].cue" saved
@@ -36,8 +41,15 @@
let audioFile = argv['audio-file']? argv['audio-file'] : `${info.videoDetails.title}.m4a`
let output_file = argv._[1]? argv._[1] : `${info.videoDetails.title}.cue`
let forceTimestamps = argv['timestamps-only']? argv['timestamps-only'] : false;
let forceDurations = argv['timestamps-are-durations']? argv['timestamps-are-durations'] : false;
let timestampsOnly = argv['timestamps-only']? argv['timestamps-only'] : false;
if (forceTimestamps && forceDurations) {
console.error("You can't pass both --timestamps-only and timestamps-are-durations");
exit(1)
}
let res = getArtistTitle(info.videoDetails.title,{
defaultArtist: "Unknown Artist",
@@ -45,7 +57,7 @@
});
let [artist, album] = res
artist = (info.videoDetails.media ? info.videoDetails.media.artist : artist)
let tracks = parse(info.videoDetails.description, {artist,timestampsOnly})
let tracks = parse(info.videoDetails.description, {artist, forceTimestamps, forceDurations})
generate({tracks, artist, audioFile, album}, output_file)
console.log(`"${output_file}" saved`)
})
@@ -138,7 +138,7 @@
list[i].start.hh = list[i].start.mm = list[i].start.ss = 0;
list[i].end = { calc: list[i].start.calc };
list[i].start.calc = 0
list[i].start.calc = 0;
} else {
@@ -152,7 +152,10 @@
}
};
export function parse(text, options = { artist: "Unknown", timestampsOnly : false }) {
export function parse(
text,
options = { artist: "Unknown", forceTimestamps: false, forceDurations: false }
) {
_options = options;
let durations = false;
let result = text
@@ -161,7 +164,7 @@
.map(firstPass)
.map(calcTimestamp);
if (options.timestampsOnly == false) {
if (!options.forceTimestamps) {
result.forEach((current, index, list) => {
@@ -173,7 +176,7 @@
}
});
if (durations) {
if (durations || options.forceDurations == true) {
fixDurations(result);
}
}
@@ -117,7 +117,7 @@
let result = parse(
`1. Artist - Title 5:00
2. Another Artist - Another Title 4:20`,
{ timestampsOnly: true }
{ forceTimestamps: true }
);
assert.deepEqual(result[0].end, {
ts: "00:4:20",
@@ -132,6 +132,54 @@
mm: 4,
ss: 20,
calc: 260,
});
});
it("should parse timestamps as durations when forced", function() {
let result = parse(
`1. Artist - Title 1:00
2. Another Artist - Another Title 1:15`,
{ forceDurations: true }
);
assert.deepEqual(result[0], {
track: 1,
_: { left_text: "Artist - Title", right_text: "" },
title: "Title",
artist: "Artist",
end: {
ts: "00:01:00",
hh: 0,
mm: 1,
ss: 0,
calc: 60,
},
start: {
ts: "00:00:00",
hh: 0,
mm: 0,
ss: 0,
calc: 0,
},
});
assert.deepEqual(result[1], {
track: 2,
_: { left_text: "Another Artist - Another Title", right_text: "" },
title: "Another Title",
artist: "Another Artist",
start: {
ts: "00:01:00",
hh: 0,
mm: 1,
ss: 0,
calc: 60,
},
end: {
ts: "00:02:15",
hh: 0,
mm: 2,
ss: 15,
calc: 135,
},
});
});