Skip to content

Instantly share code, notes, and snippets.

@edvakf edvakf/rtmpsave.c
Created Dec 11, 2011

Embed
What would you like to do?
#include <stdio.h>
#include <stdlib.h>
#include "librtmp/rtmp.h"
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("usage : %s url ticket\n", argv[0]);
return 1;
}
// initialize rtmp object
RTMP *rtmp = RTMP_Alloc();
if (rtmp == NULL) {
printf("failed RTMP_Alloc\n");
return 1;
}
RTMP_Init(rtmp);
// build url (url must be non-constant string, so dynamically allocate memory)
char url[1024];
char *swfUrl = "http://live.nicovideo.jp/liveplayer.swf?20100531";
sprintf(url, "%s conn=S:%s swfUrl=%s", argv[1], argv[2], swfUrl);
printf("%s\n", url);
RTMP_SetupURL(rtmp, url);
if (!RTMP_Connect(rtmp, NULL)) {
printf("failed to establish RTMP connection\n");
return 1;
}
if (!RTMP_ConnectStream(rtmp, 0)) {
printf("failed to establish RTMP session\n");
return 1;
}
// open file
FILE *fp = fopen("tmp.flv", "w+");
if (fp == NULL) {
printf("failed to open file\n");
return 1;
}
// read stream and save to file
long nRead;
long size = 0;
int bufsize = 64 * 1024;
char *buf = (char *)malloc(bufsize);
do {
nRead = RTMP_Read(rtmp, buf, bufsize);
if (nRead < 0) break; // success
/*if (nRead == 0) {*/
/*printf("chunk size is zero; fail?\n");*/
/*break;*/
/*}*/
if (nRead != fwrite(buf, sizeof(char), nRead, fp)) {
printf("failed to write to file\n");
return 1;
}
size += nRead;
if (nRead > 0)
printf("total bytes read=%ld, chunk size=%ld, time=%.2fsec\n", size, nRead, (double)rtmp->m_read.timestamp/1000.0);
} while(!RTMP_ctrlC && nRead > -1 && RTMP_IsConnected(rtmp));
// finalize
free(buf);
fclose(fp);
RTMP_Close(rtmp);
RTMP_Free(rtmp);
return 1;
}
@edvakf

This comment has been minimized.

Copy link
Owner Author

commented Dec 13, 2011

コンパイル手順
MacPortsでrtmpdumpをインストールしてたら、

mkdir rtmpsave
cd rtmpsave
cp /opt/local/var/macports/distfiles/rtmpdump/rtmpdump-2.3.tgz .
tar xzf rtmpdump-2.3.tgz
cp -r rtmpdump-2.3/librtmp .
cd librtmp
make CRYPTO= SHARED=
cd ..

これでまずlibrtmpをコンパイルし、librtmp.aを作る。次に、

curl https://raw.github.com/gist/1463546/6e8cceaf0cfb2e1cbfb76b56e792691727b72df4/rtmpsave.c -o rtmpsave.c
gcc -c rtmpsave.c
gcc rtmpsave.o -L./librtmp -lrtmp -o rtmpsave

これでrtmpsave(実行ファイル)を作る。

@edvakf

This comment has been minimized.

Copy link
Owner Author

commented Dec 13, 2011

使い方
まずニコニコ動画にログインしてセッションIDを取得

curl -k -D /dev/stdout -d mail=ほにゃらら -d password=ほにゃらら https://secure.nicovideo.jp/secure/login

次に、セッションIDをcookieとしてXMLを取得

curl -b user_session=user_session_ほにゃらら 'http://watch.live.nicovideo.jp/api/getplayerstatus?v=lvほにゃらら' -o tmp.xml

XMLから動画のURLとチケットを取得。

cat tmp.xml | sed 's/.*<quesheet>\(.*\)<\/quesheet>.*/\1/'
cat tmp.xml | sed 's/.*<ticket>\(.*\)<\/ticket>.*/\1/'

URLは例えば

rtmp://nlpoca02.live.nicovideo.jp:1935/fileorigin/ts_00,/content/20111211/lv73915381_094151546000_2_aa79cc.f4v?1323769877:30:52ae97da8354004f

みたいな感じなので、これの",/content"というところを"/mp4:content"に変える。最後にrtmpsaveを使う。

./rtmpsave "ユーアールエル" "チケット"

みたいな感じ。

@edvakf

This comment has been minimized.

Copy link
Owner Author

commented Dec 13, 2011

↑をするためのRubyスクリプト

#!/usr/bin/env ruby

email = ""
password = ""

if ARGV.length < 1
  puts "usage: ruby rtmvsave.rb lv******** [cookie]"
  exit 1
end

cookie = nil

if ARGV.length == 2
  cookie = ARGV[1]
else
  cookie = nil
  header = `curl -k -D /dev/stdout -d mail=#{email} -d password=#{password} https://secure.nicovideo.jp/secure/login`
  if header =~ /(user_session=user_session_.*?);/
    cookie = $1
  end
end

exit 1 if cookie == nil

xml = `curl -b #{cookie} 'http://watch.live.nicovideo.jp/api/getplayerstatus?v=#{ARGV[0]}'`

url = nil
ticket = nil

if xml =~ /<que.*?(rtmp:\/\/.*?)<\/que>/
  url = $1.sub(",/content", "/mp4:content")
end

if xml =~ /<ticket>(.*?)<\/ticket>/
  ticket = $1
end

exit 1 if url == nil or ticket == nil

command = "./rtmpsave '#{url}' '#{ticket}'"
puts "running command:\n  #{command}"
system(command)

使い方は、メールとパスワードを入力して

ruby rtmvsave.rb lv********

と実行。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.