bin/youtube-snarf-audio

92 lines
1.9 KiB
Ruby
Executable file

#!/usr/bin/env ruby
#
# youtube-snarf-audio - Extract audio from YouTube videos
#
# Downloads YouTube videos and extracts audio to m4a format.
# Accepts YouTube URLs or just video IDs as arguments.
# Skips audio extraction if output file already exists.
#
# Usage: youtube-snarf-audio <youtube-url> [<youtube-url> ...]
#
# Examples:
# youtube-snarf-audio https://youtube.com/watch?v=abc123
# youtube-snarf-audio abc123
#
# Requires: youtube-dl, ffmpeg
require 'cgi'
require 'faraday'
require 'rack'
require 'uri'
def main
while youtube_url = ARGV.shift
puts ">>> Snarfing audio from #{youtube_url}..."
if YouTubeSnarfer.snarf(youtube_url)
sleep 60
end
end
end
class YouTubeSnarfer
attr_reader :url, :video_filename
def self.snarf(url)
new(url).snarf
end
def initialize(url)
@url = url
unless @url =~ /^http/
@url = "http://youtube.com/watch?v=#{@url}"
end
end
def snarf
encode_audio
end
def title
video_filename.sub(/\s*-\w+.mp4\s*$/, '')
end
def audio_filename
"#{title}.m4a"
end
def encode_audio
save_video
if File.exists?(audio_filename)
puts ">>> Skipping, #{audio_filename} already exists. Delete it if you want to re-extract the audio."
return false
end
cmd = "ffmpeg -i '#{video_filename}' -vn -acodec copy '#{audio_filename}'"
IO.popen(cmd) do |io|
io.each_line do |line|
puts line
end
end
true
end
def save_video
IO.popen("youtube-dl #{url}") do |io|
io.each_line do |line|
puts line
if line =~ /^\[download\] /
@video_filename =
if line =~ /Destination:/
line.split(': ').last
else
line.sub('[download] ', '').sub(' has already been downloaded', '')
end.sub(/[\s\r\n]*$/, '')
end
end
end
end
end
main if $0 == __FILE__