youtube-cue/index.js

68 lines
2.3 KiB
JavaScript
Raw Normal View History

2021-05-30 15:31:27 +00:00
#!/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'
2021-06-09 18:51:23 +00:00
import minimist from 'minimist'
2021-07-21 08:14:47 +00:00
import exit from 'process'
2021-05-30 15:31:27 +00:00
2021-06-09 18:51:23 +00:00
let argv = minimist(process.argv.slice(2), {
string: 'audio-file'
});
2021-06-28 09:34:09 +00:00
if (argv._.length <1 || argv.help ){
2021-06-09 18:51:23 +00:00
console.log(`Usage
2021-06-28 09:34:09 +00:00
$ youtube-cue [--audio-file audio.m4a] <youtube_url> [output_file]
2021-05-30 15:31:27 +00:00
Options
--help, Show help
2021-06-28 09:34:09 +00:00
--audio-file, Input Audio File (optional) that is written to the CUE sheet
The default audio file is set to %VIDEOTITLE.m4a
The default output file is set to %VIDEOTITLE.cue
where $VIDEOTITLE is the title of the YouTube video.
2021-05-30 15:31:27 +00:00
Generally the parser detects whether numbers are positional timestamps or track durations.
To enforce a desired interpretation you can use these flags:
--timestamps Parse as positional timestamps (relative to the start of the playlist)
--durations Parse as track durations
2021-07-21 08:14:47 +00:00
The above 2 are only needed to force behaviour in very specific edge cases, they should
not be required for most files.
2021-05-30 15:31:27 +00:00
Examples
2021-06-28 09:34:09 +00:00
$ 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
2021-06-28 08:50:10 +00:00
$ youtube-cue "https://youtu.be/THzUassmQwE" folklore.cue
folklore.cue saved`)
2021-06-09 18:51:23 +00:00
} else {
let url = argv._[0]
2021-05-30 15:31:27 +00:00
ytdl.getInfo(url).then(info=>{
2021-06-09 18:51:23 +00:00
let audioFile = argv['audio-file']? argv['audio-file'] : `${info.videoDetails.title}.m4a`
2021-06-28 09:34:09 +00:00
let output_file = argv._[1]? argv._[1] : `${info.videoDetails.title}.cue`
let forceTimestamps = argv['timestamps']? argv['timestamps'] : false;
2021-07-21 08:14:47 +00:00
let forceDurations = argv['durations']? argv['durations'] : false;
2021-07-21 08:14:47 +00:00
if (forceTimestamps && forceDurations) {
console.error("You can't pass both --timestamps and durations");
2021-07-21 08:14:47 +00:00
exit(1)
}
2021-05-30 15:31:27 +00:00
let res = getArtistTitle(info.videoDetails.title,{
defaultArtist: "Unknown Artist",
defaultTitle: info.videoDetails.title
});
let [artist, album] = res
artist = (info.videoDetails.media ? info.videoDetails.media.artist : artist)
2021-07-21 08:14:47 +00:00
let tracks = parse(info.videoDetails.description, {artist, forceTimestamps, forceDurations})
2021-06-09 18:51:23 +00:00
generate({tracks, artist, audioFile, album}, output_file)
2021-06-28 09:34:09 +00:00
console.log(`"${output_file}" saved`)
2021-05-30 15:31:27 +00:00
})
}