#!/usr/bin/env ruby
require 'pit'
require 'niconico'
require 'pathname'
require 'open3'
def alt_title(video_id)
xml = open("http://ext.nicovideo.jp/api/getthumbinfo/#{video_id}").read
xml.scan(%r|
(.*)|m).flatten.first || video_id
end
if ARGV.size == 0
$stderr.puts "usage: nicodl [URL...]"
exit -1
end
account = Pit::get('nicovideo', :require => {
:id => 'your nicovideo id',
:pass => 'your nicovideo password'
})
nico = Niconico.new(account[:id], account[:pass])
retry_count = 0
begin
nico.login
rescue Mechanize::ResponseReadError
retry_count += 1
if retry_count < 10
puts "login faiure. retring(#{retry_count})"
sleep 5
retry
end
$stderr.puts 'login faiure.'
exit -2
end
ARGV.each do |player_url|
video_id = Pathname(URI(player_url).path).basename.to_s
begin
# downloading video
video = nico.video(video_id)
file = "#{video.title || alt_title(video_id)}.#{video.type}".gsub(%r([\\/\?:*"'><|]), '_')
open(file, 'wb:ASCII-8BIT') do |o|
video.get_video{|body|o.write(body)}
end
rescue Mechanize::ResponseCodeError, Errno::EISDIR
# live streaming time-shift
live = nico.live(video_id)
begin
live.rtmpdump_commands(video_id).each_with_index do |cmd, i|
src = "#{video_id}-#{i+1}.flv"
dst = "#{live.title.gsub(%r([\\/\?:*"'><|]), '_')}-#{i+1}.mp4"
unless File.exist?(src)
cmd[cmd.index('-o') + 1] = "./#{src}"
begin
o, e, s = Open3.capture3(*cmd)
unless s.exitstatus == 0
$stderr.puts e
next
end
rescue Errno::ENOENT # rtmdump command not found
$stderr.puts $!
exit 1
end
else
$stderr.puts "#{src} is existent. skipping."
end
cmd = 'ffmpeg'
args = ['-i', src, '-acodec', 'copy', '-vcodec', 'copy', dst]
begin
o, e, s = Open3.capture3(cmd, *args)
unless s.exitstatus == 0
$stderr.puts e
next
end
File.delete(src)
rescue Errno::ENOENT
if cmd == 'avconv'
$stderr.puts "ffmpeg or avconv not found."
else # retry with avconv command instead of ffmpeg
cmd = 'avconv'
retry
end
end
end
rescue Niconico::Live::TicketRetrievingFailed
$stderr.puts $!
exit 2
end
end
end