class Ripdiru::DownloadTask

Constants

SCHEDULE_URL
TMPDIR

Attributes

bitrate[RW]
buffer[RW]
cache[RW]
outdir[RW]
station[RW]

Public Class Methods

new(station = nil, duration = 1800, *args) click to toggle source
# File lib/ripdiru.rb, line 21
def initialize(station = nil, duration = 1800, *args)
  unless station
    abort "Usage: ripdiru [station-id]"
  end
  @station = station
  @channel = channel
  @duration = duration
  @cache = CacheDir.new(TMPDIR)
  @buffer = ENV['RIPDIRU_BUFFER'] || 60
  @outdir = ENV['RIPDIRU_OUTDIR'] || "#{ENV['HOME']}/Music/Radiru"
  @bitrate = ENV['RIPDIRU_BITRATE'] || '48k'
end

Public Instance Methods

abort(msg) click to toggle source
# File lib/ripdiru.rb, line 121
def abort(msg)
  puts msg
  exit 1
end
channel() click to toggle source
# File lib/ripdiru.rb, line 34
def channel
  case station
    when "NHK1"
      @aspx="http://mfile.akamai.com/129931/live/reflector:46032.asx"
      @mms_ch="netr1"
    when "NHK2"
      @aspx="http://mfile.akamai.com/129932/live/reflector:46056.asx"
      @mms_ch="netr2"
    when "FM"
      @aspx="http://mfile.akamai.com/129933/live/reflector:46051.asx"
      @mms_ch="netfm"
    else
      puts "invalid channel"
  end
end
mms_url() click to toggle source
# File lib/ripdiru.rb, line 81
def mms_url
  f = open(@aspx)
  doc = REXML::Document.new(f)

  mms_url =  REXML::XPath.first(doc, "//ENTRY/REF").attribute("HREF").to_s
  mms_url.sub!("mms://", "mmsh://")
end
now_playing(station) click to toggle source
# File lib/ripdiru.rb, line 58
def now_playing(station)
  now = Time.now

  f = open(SCHEDULE_URL)
  xml = REXML::Document.new(f)

  REXML::XPath.each(xml, "//item") do |item|
    if val(item, "ch") == @mms_ch && val(item, "index") == '0'
      from, to = parse_time(val(item, "starttime")), parse_time(val(item, "endtime"))
      start_time = now.to_i + buffer
      return Program.new(
        id: now.strftime("%Y%m%d%H%M%S") + "-#{station}",
        station: station,
        title: val(item, "title"),
        from: from,
        to: to,
        duration: to.to_i - from.to_i,
        info: val(item, "link"),
      )
    end
  end
end
parse_time(str) click to toggle source
# File lib/ripdiru.rb, line 54
def parse_time(str)
  DateTime.strptime("#{str}+0900", "%Y-%m-%d %H:%M:%S%Z").to_time
end
run() click to toggle source
# File lib/ripdiru.rb, line 89
def run
  program = now_playing(station)

  duration = program.recording_duration + buffer

  tempfile = "#{TMPDIR}/#{program.id}.mp3"
  puts "Streaming #{program.title} ~ #{program.to.strftime("%H:%M")} (#{duration}s)"
  puts "Ripping audio file to #{tempfile}"

  command = %W(
    ffmpeg -y -i #{mms_url} -vn
    -loglevel error
    -metadata author="NHK"
    -metadata artist="#{program.station}"
    -metadata title="#{program.title} #{program.effective_date.strftime}"
    -metadata album="#{program.title}"
    -metadata genre=Radio
    -metadata year="#{program.effective_date.year}"
    -acodec libmp3lame -ar 44100 -ab #{bitrate} -ac 2
    -id3v2_version 3
    -t #{duration}
    #{tempfile}
  )

  Signal.trap(:INT) { puts "Recording interupted by user"}
  system command.join(" ")

  FileUtils.mkpath(outdir)
  File.rename tempfile, "#{outdir}/#{program.id}.mp3"

end
val(element, path) click to toggle source
# File lib/ripdiru.rb, line 50
def val(element, path)
  element.get_text(path)
end