diff --git a/index.js b/index.js index a8e0da3..1aa9d3e 100755 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ 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,6 +24,10 @@ if (argv._.length <1 || argv.help ){ 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" @@ -37,7 +42,14 @@ if (argv._.length <1 || argv.help ){ let output_file = argv._[1]? argv._[1] : `${info.videoDetails.title}.cue` - let timestampsOnly = argv['timestamps-only']? argv['timestamps-only'] : false; + let forceTimestamps = argv['timestamps-only']? argv['timestamps-only'] : false; + + let forceDurations = argv['timestamps-are-durations']? argv['timestamps-are-durations'] : 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 @@ if (argv._.length <1 || argv.help ){ }); 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`) }) diff --git a/src/parser.js b/src/parser.js index 36609b3..77afabe 100644 --- a/src/parser.js +++ b/src/parser.js @@ -138,7 +138,7 @@ var fixDurations = function(list) { list[i].start.hh = list[i].start.mm = list[i].start.ss = 0; // And end at the right time list[i].end = { calc: list[i].start.calc }; - list[i].start.calc = 0 + list[i].start.calc = 0; } else { // All the others tracks start at the end of the previous one // And end at start time + duration @@ -152,7 +152,10 @@ var fixDurations = function(list) { } }; -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 @@ export function parse(text, options = { artist: "Unknown", timestampsOnly : fals .map(firstPass) .map(calcTimestamp); - if (options.timestampsOnly == false) { + if (!options.forceTimestamps) { // If our timestamps are not in increasing order // Assume that we've been given a duration list instead result.forEach((current, index, list) => { @@ -173,7 +176,7 @@ export function parse(text, options = { artist: "Unknown", timestampsOnly : fals } }); - if (durations) { + if (durations || options.forceDurations == true) { fixDurations(result); } } diff --git a/test/parser_test.js b/test/parser_test.js index 27fd294..2bfa933 100644 --- a/test/parser_test.js +++ b/test/parser_test.js @@ -117,7 +117,7 @@ describe("Parser", function() { 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", @@ -135,6 +135,54 @@ describe("Parser", function() { }); }); + 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, + }, + }); + }); + it("should parse taylor swift", function() { let result = parse(`0:00 the 1 3:29 cardigan