Mac でニコニコチャンネルを予約録画

※ただし Tiger 以降に限る。
どうやら安定運用できてるようなので、やり方を忘れないうちにメモメモ。

用意するもの

ファイル配置

# ls -l /Library/LaunchDaemons/
-rw-r--r--  1 root  wheel  634 Oct 15 22:42 org.mobitan.nicoch-dl.plist
# ls -l /Users/(Macユーザー名)/
-rwxr-xr-x   1 (Macユーザー名)  staff    2468 Oct 18 03:07 nicoch-dl.rb
-rwxr-xr-x   1 (Macユーザー名)  staff   18387 Oct 14 20:44 nicovideo-dl
drwxrwxrwx  15 (Macユーザー名)  staff     510 Oct 17 20:56 video

/Library/LaunchDaemons/org.mobitan.nicoch-dl.plist

この例だと毎日 3 時 33 分に発動。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>org.mobitan.nicoch-dl</string>
	<key>StartCalendarInterval</key>
	<dict>
		<key>Minute</key>
		<integer>33</integer>
		<key>Hour</key>
		<integer>3</integer>
	</dict>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/bin/ruby</string>
		<string>/Users/(Macユーザー名)/nicoch-dl.rb</string>
	</array>
	<key>UserName</key>
	<string>(Macユーザー名)</string>
	<key>WorkingDirectory</key>
	<string>/Users/(Macユーザー名)</string>
</dict>
</plist>

root で↑を書いて保存。その後 launchctl load で読み込むか、マシンを再起動。

~/nicoch-dl.rb

#!/usr/bin/env ruby -Ku
# 
# 	ニコニコチャンネル最新話ダウンロード
# 	by mobitan  2011/10/15
# 

# URL を空白区切りで書き並べる。各ページからのリンク先のうち
# 動画 ID が最も大きい=最新の動画がダウンロードされる。
channels = %w!
http://ch.nicovideo.jp/channel/ikamusume-02
http://ch.nicovideo.jp/channel/future-diary
!
channels = ARGV if !ARGV.empty? # デバッグ用
Username = "(ニコニコ動画アカウント)"
Password = "(ニコニコ動画パスワード)"
SaveFolder = "./video"
Downloader = "./nicovideo-dl"
$mylogfile = File.basename($0, ".*") + ".log"
$dllogfile = File.basename(Downloader, ".*") + ".log"
Interval = 15 # sec

require "open-uri"
require "logger"

def download_latest_video_in(url)
	# 最新話の視聴 URL を取得
	content = ""
	open(url) do |f|
		content = f.read
	end
	video_url = content.scan(%r!http://(?:\w+\.)?nicovideo\.jp/watch/\w+!).uniq.sort.last
	
	# タイトルを取得
	cmdline = "#{Downloader} -u #{Username} -p #{Password} --title-nfinder --print-filename #{video_url}"
	message = `#{cmdline}`.chomp
	sleep Interval
	if message =~ /Error:/
		print "Retrieving #{video_url} ... error!\n"
		return
	end
	prettyname = message.chomp
	video_id = prettyname[/\(\w+\)/]
	print "Downloading \"#{prettyname}\" ... "
	
	# ダウンロード
	stocks = Dir.glob("#{SaveFolder}/**/*#{video_id}.*")
	if (!stocks.reject{|item| item[/\/\[エコノミー\]/] }.empty?) || (!stocks.empty? && prettyname[/^\[エコノミー\]/])
		print "skipped.\n"
	else
		cmdline = "#{Downloader} -u #{Username} -p #{Password} #{video_url}"
		message = `#{cmdline} | tee -a #{$dllogfile}`
		sleep Interval
		if /^Video data saved to (.*)$/ =~ message
			print "done.\n"
			File.rename($1, "#{SaveFolder}/#{prettyname}")
		else
			print "failed!\n"
		end
	end
	
	# 標準画質のファイルがあるならエコノミーのファイルを削除する
	saved = Dir.glob("#{SaveFolder}/**/*#{video_id}.*").partition{|item| item[/\/\[エコノミー\]/] }
	if !saved[1].empty?
		saved[0].each do |item|
			File.delete(item)
		end
	end
end

$stdout.sync = true
log = Logger.new($mylogfile)
log.info("Start")
File.delete($dllogfile) if File.exist?($dllogfile)
channels.each do |ch_url|
	download_latest_video_in(ch_url)
end
log.info("Finish")

nicovideo-dl と↑を同じディレクトリに置いて両方に実行権限を与える。

$ chmod 755 nicoch-dl.rb nicovideo-dl

*1:パスワードをスクリプト内に平文で書くので、これ専用のアカウントを作るのが望ましい