Skip to content

Instantly share code, notes, and snippets.

@VityaSchel
Last active October 18, 2023 20:11
Show Gist options
  • Save VityaSchel/7779dea70d0eafa4c5ecc6bf6a970231 to your computer and use it in GitHub Desktop.
Save VityaSchel/7779dea70d0eafa4c5ecc6bf6a970231 to your computer and use it in GitHub Desktop.
Youtube cutter (Node.js, cli)

Youtube cutter

Follow these steps:

  1. Install yt-dlp somewhere on your computer and make sure it's accessible via PATH
  2. create new folder anywhere on your computer
  3. download cut.js here
  4. download pacakge.json here
  5. run npm i in this folder (npm and node must be installed)
  6. (RECOMMEND) download cutyt.cmd into this folder, change path to cut.js to yours, go to windows settings and add path to the folder to Environmental variable PATH, then you can run this as:
cutyt "https://www.youtube.com/watch?v=q4HSTqu9qVg"

which will prompt you some settings such as format, time ranges and URL if you forgot to specify it as argument

someday I will use this in my yt-dlp GUI which I will definetely develop... someday...

import { spawn } from 'child_process'
import prompts from 'prompts'
import trash from 'trash'
let url = process.argv[2]
if (!url) {
url = await prompts([
{
type: 'text',
name: 'url',
message: 'Video URL'
}
])
}
const formatSelector = spawn('yt-dlp', ['-F', url])
formatSelector.stdout.on('data', data => console.log(data.toString('utf-8')))
formatSelector.stderr.on('data', data => console.error(data.toString('utf-8')))
await new Promise(resolve => formatSelector.on('close', resolve))
const responses = await prompts([
{
type: 'number',
name: 'videoformat',
message: 'Video format ID',
initial: '399'
},
{
type: 'number',
name: 'audioformat',
message: 'Audio format ID',
initial: '251'
},
])
const timerange = await prompts([
{
type: 'text',
name: 'from',
message: 'From (00:00:00 or 00:00)'
},
{
type: 'text',
name: 'to',
message: 'To (00:00:00 or 00:00)'
},
])
const videoformatURLprocess = spawn('yt-dlp', ['-g', '-f', responses.videoformat, url])
let videoformatURL = ''
videoformatURLprocess.stdout.on('data', data => videoformatURL += data.toString('utf-8'))
videoformatURLprocess.stderr.on('data', data => console.error(data.toString('utf-8')))
await new Promise(resolve => videoformatURLprocess.on('close', resolve))
const audioformatURLprocess = spawn('yt-dlp', ['-g', '-f', responses.audioformat, url])
let audioformatURL = ''
audioformatURLprocess.stdout.on('data', data => audioformatURL += data.toString('utf-8'))
audioformatURLprocess.stderr.on('data', data => console.error(data.toString('utf-8')))
await new Promise(resolve => audioformatURLprocess.on('close', resolve))
const audioFilename = 'cutyt_' + Date.now() + '_aud.opus'
const videoFilename = 'cutyt_' + Date.now() + '_vid.mp4'
const resultFilename = url.match(/https:\/\/.*\?v=(.+)/)[1] + '.mp4'
const download = async (url, filename, consolePrefix) => {
console.log('ffmpeg', ['-ss', timerange.from, '-to', timerange.to, '-i', url, filename].join(' '))
const downloadingProcess = spawn('ffmpeg', ['-ss', timerange.from, '-to', timerange.to, '-i', url, filename])
downloadingProcess.stdout.on('data', data => console.log(consolePrefix, data.toString('utf-8')))
downloadingProcess.stderr.on('data', data => console.error(consolePrefix, data.toString('utf-8')))
await new Promise(resolve => downloadingProcess.on('close', resolve))
}
await Promise.all([
download(audioformatURL.replace('\n', ''), audioFilename, 'audio_stream:'),
download(videoformatURL.replace('\n', ''), videoFilename, 'video_stream:'),
])
const mergeStreams = spawn('ffmpeg', ['-i', audioFilename, '-i', videoFilename, '-c:v', 'copy', resultFilename])
await new Promise(resolve => mergeStreams.on('close', resolve))
await trash([audioFilename, videoFilename])
console.log('Success!', resultFilename)
node C:\Users\VityaSchel\Documents\cut-yt\cut.js %*
# Follow instructions below to make "cutyt" command work in MacOS or any shell terminal
# 1. Create "cutyt" file without extension
touch cutyt
# 2. Make it executable
chmod +x cutyt
# 3. Put it into cutyt (replace path to yours):
node /Users/VITA/Documents/cutyt/cut.js $1
# 3. Add to ~/.zshrc:
export PATH=/Users/VITA/Documents/cutyt:$PATH
# 4. Source it
source ~/.zshrc
# 5. Use
cuyt "https://www.youtube.com/watch?v=rAgGBkA1vI8"
{
"name": "cut-yt",
"version": "1.0.0",
"description": "",
"main": "cut.js",
"type": "module",
"license": "ISC",
"dependencies": {
"prompts": "^2.4.2",
"trash": "^8.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment