/ youtube-snarf-audio
youtube-snarf-audio
1 #!/usr/bin/env ruby 2 # 3 # youtube-snarf-audio - Extract audio from YouTube videos 4 # 5 # Downloads YouTube videos and extracts audio to m4a format. 6 # Accepts YouTube URLs or just video IDs as arguments. 7 # Skips audio extraction if output file already exists. 8 # 9 # Usage: youtube-snarf-audio <youtube-url> [<youtube-url> ...] 10 # 11 # Examples: 12 # youtube-snarf-audio https://youtube.com/watch?v=abc123 13 # youtube-snarf-audio abc123 14 # 15 # Requires: youtube-dl, ffmpeg 16 17 require 'cgi' 18 require 'faraday' 19 require 'rack' 20 require 'uri' 21 22 def main 23 while youtube_url = ARGV.shift 24 puts ">>> Snarfing audio from #{youtube_url}..." 25 if YouTubeSnarfer.snarf(youtube_url) 26 sleep 60 27 end 28 end 29 end 30 31 class YouTubeSnarfer 32 33 attr_reader :url, :video_filename 34 35 def self.snarf(url) 36 new(url).snarf 37 end 38 39 def initialize(url) 40 @url = url 41 unless @url =~ /^http/ 42 @url = "http://youtube.com/watch?v=#{@url}" 43 end 44 end 45 46 def snarf 47 encode_audio 48 end 49 50 def title 51 video_filename.sub(/\s*-\w+.mp4\s*$/, '') 52 end 53 54 def audio_filename 55 "#{title}.m4a" 56 end 57 58 def encode_audio 59 save_video 60 if File.exists?(audio_filename) 61 puts ">>> Skipping, #{audio_filename} already exists. Delete it if you want to re-extract the audio." 62 return false 63 end 64 cmd = "ffmpeg -i '#{video_filename}' -vn -acodec copy '#{audio_filename}'" 65 IO.popen(cmd) do |io| 66 io.each_line do |line| 67 puts line 68 end 69 end 70 true 71 end 72 73 def save_video 74 IO.popen("youtube-dl #{url}") do |io| 75 io.each_line do |line| 76 puts line 77 78 if line =~ /^\[download\] / 79 @video_filename = 80 if line =~ /Destination:/ 81 line.split(': ').last 82 else 83 line.sub('[download] ', '').sub(' has already been downloaded', '') 84 end.sub(/[\s\r\n]*$/, '') 85 end 86 end 87 end 88 end 89 90 end 91 92 main if $0 == __FILE__