ストリーミングを保存しようと頑張ったときの軌跡

ストリーミングを保存しようと頑張ったときの軌跡


```nicolive.rb

require "net/http"
require "net/https"
require "uri"
require "rexml/document"

class NicoLiveException < StandardError; end

class NicoLive
  attr_accessor :mail_tel, :password
  
  def initialize(mail_tel = nil, password = nil)
    @mail_tel = mail_tel
    @password = password
  end

  def login(mail_tel = nil, password = nil)

    mail_tel = @mail_tel unless mail_tel
    password = @password unless password

#    uri = URI.parse("https://sesesecure.nicovideo.jp/secure/login?site=niconico")
    uri = URI.parse("https://secure.nicovideo.jp/secure/login?site=niconico")
    
    request = Net::HTTP::Post.new(uri.request_uri)
    request.body = "mail_tel=" + mail_tel + "&password=" + password
    
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    http.open_timeout = 3
    http.read_timeout = 3
    
    # for debug output
#   http.set_debug_output $stderr
    
    begin
      http.start do |h|

        response = h.request(request)
      
        # for debug output
#        p response
#        response.each do |name, value|
#          puts "header>" + name + " : " + value + "\n"
#        end
      
        user_session = nil
        
        cookies = response.get_fields('Set-Cookie')
        cookie = cookies.find do |str|
          k, v = str[0...str.index(';')].split('=')
          next unless k == "user_session"
          v.index('user_session')
        end

        unless cookie
          raise NicoLiveException, "no user_session cookie error." #=> no user_session cookie error. (NicoLiveException)
        end

        k, user_session = cookie[0...cookie.index(';')].split('=')
        return user_session
     
      end # http.start do |h|

    rescue Timeout::Error
      raise NicoLiveException, "timeout error." #=> timeout error. (NicoLiveException)
    rescue
      raise NicoLiveException, "login error." #=> login error. (NicoLiveException)
   end # begin

  end

  def getPlayerStatus(id)
#    print "id = " + id + "\n"
    user_session = login
#    puts user_session

    uri = URI.parse("http://watch.live.nicovideo.jp/api/getplayerstatus/" + id)
    
    request = Net::HTTP::Get.new(uri.request_uri)
    request["Cookie"] = "user_session="+user_session

#    request.body = "mail_tel=" + mail_tel + "&password=" + password
    
    http = Net::HTTP.new(uri.host, uri.port)
    http.open_timeout = 3
    http.read_timeout = 3
    
    # for debug output
#    http.set_debug_output $stderr
    
    begin
      http.start do |h|
        response = h.request(request)
#        puts response.body
        doc = REXML::Document.new response.body
        status = doc.elements["getplayerstatus"].attributes['status']
        if status == "fail"
          raise NicoLiveException, "getplayerstatus failed." #=> getplayerstatus failed. (NivoLiveException)
        end
        return doc
      end
    end
 
  end

end

# script

liveid = nil
if ARGV[0]
  liveid = ARGV[0]
else
  puts "Usage: nicolive.rb liveid"
  exit
end

mail_tel = "YOUR_EMAIL_ADDRESS"
password = "YOUR_PASSWORD"

live = NicoLive.new
live.mail_tel = mail_tel
live.password = password
status = live.getPlayerStatus(liveid)
puts status

url = status.elements['getplayerstatus/rtmp/url'].text
puts "rtmp/url: " + url if url

ticket = status.elements['getplayerstatus/rtmp/ticket'].text
puts "rtmp/ticket: " + ticket

contents = status.elements['getplayerstatus/stream/contents_list/contents'].text
puts "stream/contents_list/contents = " + contents

puts "command:"

contents = contents["rtmp:".length...contents.length] if contents.index("rtmp:rtmp:")

if url
  puts "~/git/rtmpdump-nico-live/rtmpdump -o ~/out.flv -vr \"#{url}\" -C S:\"#{ticket}\" -N \"#{contents}\""
else
  contents = contents["limelight:".length...contents.length] if contents.index("limelight:")
  puts "~/git/rtmpdump-nico-live/rtmpdump -o ~/out.flv -vr \"#{contents}\" -C S:\"#{ticket}\" -N \"#{contents}\""
end
```