PDFファイルをKobo Glo向けのCBZファイルに変換する

Kobo Glo で PDF を読もうとしたら異様に動作が重かったです。その PDF ファイルだけかも知れませんが。

仕方が無いので CBZ ファイル(画像ファイルを ZIP でかためたもの)に変換するスクリプトを作成しました。文字情報は失われますが、検索とかコピペとかしない文書なので軽さ最優先です。

pdftocbz.sh hogehoge.pdf

と実行すると、同じ場所に最適化されたCBZファイルが出来ます。元のPDFファイルにタイトルや著者名が埋めこまれていると、それを使って「[著者名] タイトル.cbz」みたいなファイル名になります。

tdtds/kindlizer · GitHub を手本に作りました。やっと convert コマンドの使い方が分かってきた気がします、今さら。

広告

響 – Hibiki Radio Station – 録音スクリプト修正

Hibiki Radio Station の番組詳細ページの Windows Media Player ファイルを保存するためのスクリプトです。
本当はTOPページで rtmpdump するのがいいんでしょうけど手っ取り早いので。
asx ファイルが変わったみたいので対応しました。

02/05追記:なんだか頻繁に録音失敗するので、一回リトライするようにしました。っていうか mimms にレジュームオプションなんてあったんですね……。

02/13追記:mimmsは途中終了してもエラーにならないらしいので ”||” 演算子の意味が無い……。どんな場合でも二回mimmsするようにしました。

#!/bin/sh -e
# hibiki.sh ver.0.5.6 (2013-02-13)
# require wget, ruby, and mimms
TMPFILE="/var/tmp/tmp.$$"
trap 'rm -f ${TMPFILE}' EXIT

if [ $# -eq 1 ]; then
  STR=$1

  # save asx file
  wget -q -O - http://hibiki-radio.jp/description/${STR} | grep WMV | ruby -ruri -e 'puts URI.extract(ARGF.read, "http")' | head -1 | xargs wget -q -O ${TMPFILE}
  if [ -z ${TMPFILE} ]; then
    echo "download ERROR"
    exit 1
  fi
  TITLE=`cat ${TMPFILE} | ruby -rrexml/document -e 'puts REXML::Document.new(ARGF).elements["ASX/entry/title"].text'`
  WMVFILE=`cat ${TMPFILE} | ruby -rrexml/document -e 'puts REXML::Document.new(ARGF).elements["ASX/entry/Ref"].attributes["href"]'`
  if test a"$TITLE" = a"" ; then
    echo "asx detection failed."
    exit 1
  fi

  mimms -r ${WMVFILE} "${TITLE}.asf"
  mimms -r ${WMVFILE} "${TITLE}.asf"

else
  echo "usage: `basename $0` STRING"
fi

WebRadioRecorder/hibiki.sh at master · unot/WebRadioRecorder · GitHub

そういえば音泉の録音用にスクリプト書いたけど

公開してませんでした。

追記:スクリプト修正しました。

いやー、我ながら気合い入ったスクリプトですね。rubyの部分は適当ですけど。あ、opensslとwgetとrubyが必要なのでご注意を。

引数なしで実行すると本日更新分を順に録音するか聞いてきます。”q” と打ってエンターキーを押すと終了、”n” だと次の番組。

a オプション
最新更新分じゃなくても録音。
y オプション
昨日更新分を録音。
v オプション
verbose モード。wgetの様子が見えたり一時ファイルを消すか聞いてきます。
w オプション
週番号指定して録音。0から6までで0が日曜日。
#!/bin/bash -e
# onsen.sh Ver. 0.8.4 (2013.02.02)
# recording tool for onsen.ag
# require openssl, wget and ruby

# target date
GOTDATE=`date +%y%m%d`
# precode of POST data
PRECODE=onsen`date +%w%d%H`
# POST data
PDATA="code=`echo $PRECODE | openssl dgst -md5 | sed -e 's/(stdin)= //'`\&file%5Fname=regular%5F"
# week number
REGXMLNUM=`date +%w`
# onsen URL
URL="http://onsen.ag/getXML.php?`date +%s`000"
# tmp file
TMPFILE="/var/tmp/tmp.$$"

AFLAG=FALSE
WGETOPTION=-q
RMOPTION=
OPT=
while getopts ayvw: OPT
do
  case $OPT in
    a) AFLAG=TRUE
       ;; # with all programs on GOTDATE
    y) GOTDATE=`TZ=JST+15 date +%y%m%d`
       REGXMLNUM=`TZ=JST+15 date +%w`
       ;; # yesterday
    v) WGETOPTION=
       RMOPTION=-i
       ;; # verbose mode
    w) REGXMLNUM=$OPTARG
       ;; # indicate week number
    \?) echo "Usage: `basename $0` [-avy] [-w weeknumber]" 1>&2
        exit 1
        ;;
  esac
done
shift `expr $OPTIND - 1`

# download regular XML file
wget ${WGETOPTION} --post-data="${PDATA}${REGXMLNUM}" ${URL} -O ${TMPFILE}

# number of program
PROGNUM=`grep -c '<title>' ${TMPFILE} | cut -d ":" -f2`
#echo "番組数: $PROGNUM"
# index number
i=1
while test ${PROGNUM} -gt 0
do
  PROGNUM=`expr ${PROGNUM} - 1`
  ISNEW=`cat ${TMPFILE} | ruby -rrexml/document -e "puts REXML::Document.new(ARGF).elements[\"data/regular/program/isNew[${i}]\"].text"`
  if test ${AFLAG} = TRUE -a ${ISNEW} = 0 ; then
    ISNEW=1
  fi
  TITLE=`cat ${TMPFILE} | ruby -rrexml/document -e "puts REXML::Document.new(ARGF).elements[\"data/regular/program/title[${i}]\"].text"`
  NUM=`cat ${TMPFILE} | ruby -rrexml/document -e "puts REXML::Document.new(ARGF).elements[\"data/regular/program/number[${i}]\"].text"`
  UPDATE=`cat ${TMPFILE} | ruby -rrexml/document -e "puts REXML::Document.new(ARGF).elements[\"data/regular/program/update[${i}]\"].text" | tr '/' '月' | sed -e 's/$/日配信/'`
  MP3FILE=`cat ${TMPFILE} | ruby -rrexml/document -e "puts REXML::Document.new(ARGF).elements[\"data/regular/program/fileUrlIphone[${i}]\"].text"`
  i=`expr ${i} + 1`
  if test ${ISNEW} != 1 ; then
    continue
  fi
  # Question
  echo -n "Record \"${TITLE} 第${NUM}回(${UPDATE}).mp3\"?[Yes/no/quit] "
  read ANSWER
  case `echo "$ANSWER" | tr [A-Z] [a-z]` in
  no | n ) ANSWER=no
           continue
           ;;
  quit | q ) break
             ;;
  * ) ANSWER=yes
      ;;
  esac

  wget ${WGETOPTION} -O "${TITLE} 第${NUM}回(${UPDATE}).mp3" ${MP3FILE}
done

rm ${RMOPTION} ${TMPFILE}
exit 0

参考

Webラジオ 質問掲示板 兼 ハヤテのごとく!応援同盟 雑談掲示板

radikoの仕様が変わってた

ことに、2回も録音失敗してから気付きました。

上記リンク先で

237 :まちがって名前消しちゃいました。:2012/10/24(水) 16:49:48.22 ID:???
player_2.0.1.00.swf

player_3.0.0.01.swf

swfextract -b 5

swfextract -b 14

radiko.smartstream.ne.jp

w-radiko.smartstream.ne.jp

simul-stream

simul-stream.stream

_defInst_

_definst_

これでイケた。

とあったのでちまちまスクリプトを修正してたら、下のGistでエレガントに解決してました。

wget -q "http://radiko.jp/v2/station/stream/${channel}.xml"
stream_url=`echo "cat /url/item[1]/text()" | xmllint --shell ${channel}.xml | tail -2 | head -1`
url_parts=(`echo ${stream_url} | perl -pe 's!^(.*)://(.*?)/(.*)/(.*?)$/!$1://$2 $3 $4!'`)
rm -f ${channel}.xml
#
# rtmpdump
#
rtmpdump -v \
    -r ${url_parts[0]} \
    --app ${url_parts[1]} \
    --playpath ${url_parts[2]} \
    -W $playerurl \
    -C S:"" -C S:"" -C S:"" -C S:$authtoken \
    --live \
    --flv $output

このままだとcronで予約録音できないので少々手を入れて使ってます。

rtmpdumpでNHK-FMを録音する

PC(というかMac)でNHK-FMを録音できないかと頼まれたのでやってみました。

必要なもの

  • rtmpdump

ストリーミングを保存するコマンド。ソースからビルド(後述)。

  • ffmpeg

保存したflvファイルを変換するコマンド。Homebrewでインストール。

rtmpdump のビルド

Homebrew で手に入る version 2.3 だと失敗するらしいのでソースからビルド。

git clone git://git.ffmpeg.org/rtmpdump
cd rtmpdump
make SYS=darwin
sudo make install SYS=darwin

make install のときも SYS=darwin が要るんですな。

録音スクリプト

以下のようなスクリプト (nhkfmrec.sh) を作りました。
引数なしで実行するとその時点から2時間+2分の録音が始まります。
第一引数で録音時間を分で指定することができます。念のため内部で2分追加してますが。
RTMPDUMP, FFMPEG, SAVEDIRは環境に応じて変更してください。

#!/bin/sh
XDATE=`date -v+1M +"%Y-%m%d-%H%M"`
STOPMINS=${1:-120}
STOPSECS=`expr ${STOPMINS} \* 60 + 120`
RTMPDUMP=/usr/local/bin/rtmpdump
FFMPEG=/usr/local/bin/ffmpeg
AFCONVERT=/usr/bin/afconvert
SAVEDIR=/Users/hoge
FLVFILE=${SAVEDIR}/NHK-FM_${XDATE}.flv
AACFILE=${FLVFILE%.flv}.aac
${RTMPDUMP} --rtmp "rtmpe://netradio-fm-flash.nhk.jp" \
    --playpath 'NetRadio_FM_flash@63343' \
    --app "live" \
    -W http://www3.nhk.or.jp/netradio/files/swf/rtmpe.swf \
    --live \
    -B $STOPSECS \
    -o ${FLVFILE}
${FFMPEG} -i ${FLVFILE} -vn -acodec copy ${AACFILE}
if [ $? != 0 ]; then
    ${FFMPEG} -i ${FLVFILE} ${AACFILE}
fi
${AFCONVERT} -f m4af -d aach -b 48000 ${AACFILE}
#rm ${FLVFILE} ${AACFILE}
exit 0

rtmpdumpコマンドで録音したファイルを flv → aac → m4a と変換してます。
--rtmp--playpath の値を変えればNHK第一や第二も録音できるはずです。

タイマー録音

Mac は完全に launchd に移行してるのかと思ったら cron も動いてるので cron で予約録音しました。launchdのためにXML書くの面倒臭いです。
crontab -e を実行して以下のように入力します。ZZコマンドで保存して終了。

59 20 * * 0 /path/to/nhkfmrec.sh 120

この設定だと「毎週日曜日20時59分に /path/to/nhkfmrec.sh 120 を実行」という意味になります。

参考

ストリーミングについての拘り

またもこの weblog システムにログインできず……一週間振りの更新となりました。あーもう!

 ところで Lantis-net とかメディアファクトリーの Web ラジオのストリーミングは Mac OS X 環境で録音しようとしても一筋縄ではいきません。音泉とか animate.tv とかは素直なのに……。素直にストリーミングで聴けと?或いはキャッシュからサルベージしろと。

 lantis は特に被害甚大。ねぶらとか超自然災害対策室とか大好きなのにー。ストリーミングの定義ファイルが他所の様に asx じゃなくて wsx になってます。asx だと直接、音声データの在り処が書いてあるのに、wsx だとループしてしまいます。

 結局、VMware Fusion で Windows 7 β を立ち上げて、そこから GetASFStream というソフトで録音しています。このソフト、Wine じゃ碌に動かないんですよねえー。

 メディファクラジオは……最近 asx に記述する形から JavaScript で新たなページに誘導する形になりました。まあ、その新たなページに一応 asx の情報が書かれてあるので、そこから mimms に食わせています。面倒臭いですが、これくらいなら何とか。

ΔE94 をワンライナーで

L*a*b* 空間の単純な距離である色差 ΔE (CIE 1976) に比べて少々ややこしい ΔE94 (CIE 1994) を一行で計算してみました。
awk 使ったから実は一行じゃありませんが。

まず色差を算出したい、対となる測色データ file1, file2 を用意します。

file1

95.05 2.00 -8.38
94.90 2.02 -8.26
94.86 2.03 -8.38
94.70 1.98 -8.33
94.43 1.99 -8.18

file2

94.95 1.90 -8.35
94.98 1.94 -8.32
94.90 1.91 -8.27
94.69 1.90 -8.26
94.30 1.92 -8.18

左から順に L*, a*, b* 値です。
後は以下のコマンドを実行すれば ΔE94 が一列に表示されます。 Matlab や GNU Octave を起動してごちゃごちゃするより気が楽ですね。

# paste file1 file2 | awk '{ dL = $1 - $4; dC = sqrt($2 ^2 + $3 ^2) - sqrt($5 ^2 + $6 ^2); dH = sqrt(($2 - $5) ^2 + ($3 - $6) ^2 - dC ^2); cone = sqrt($2 ^2 + $3 ^2); print sqrt(dL^2 + (dC/(1 + 0.045 * cone))^2 + (dH/(1 + 0.015 * cone))^2) }'

出来れば ΔE00 (CIE 2000) や CAM 02 も計算できるようになりたいのですが……技術文書読むのが面倒くさいです(爆)。

音泉リニューアルの顛末

取り敢えず wmv の変換は ffmpeg を使うことにしました。
以下の記事を参考に Macports で ffmpeg をインストールしました。

変換は ffmpeg -i input.wmv output.mp3 のような感じで。

え゙ー、これだけではなんなので録音スクリプトをバージョンアップしました。


#! /bin/sh
# onsen.sh Ver. 0.3
GOTDATE=`date +%y%m%d`
TFLAG=FALSE
TITLE=
OPT=
while getopts ty OPT
do
  case $OPT in
    t) TFLAG=TRUE
       ;;
    y) GOTDATE=`TZ=JST+15 date +%y%m%d`
       ;;
    \?) echo "Usage: $0 [-ty] hoge" 1>&2
      exit 1
      ;;
  esac
done
shift `expr $OPTING - 1`

if [ $# -eq 1 ]; then
  STR=$1
  URL=http://onsen.ag/asx/${STR}${GOTDATE}.asx
  MMS=`wget -q -O - $URL | grep $STR |
    awk ’{gsub(/"/,"",$4);print $4;}’`
   if [ $TFLAG = TRUE ]; then
     TITLE=`wget -q -O - $URL | nkf -w |
          sed -n 's/<TITLE>\(.*\)<\/TITLE>/\1/p' | tr -d "\r"`.wmv
   fi
  mimms $MMS $TITLE
else
  echo "Usage: $0 [-ty] hoge" 1>&2
fi

前バージョンでは onsen.sh hoge のみだったのですが、今回は t, y のオプションを追加しました。 t オプションはタイトルをファイル名として保存します。 y オプションは前日分のラジオを録音する場合に使います。いやー、残業が多いと当日に録音できない場合があるんですよ。

視力ががが

元々、左眼が近視だったのですが、右眼もそれにつられて悪くなってきました。眼が疲れてくると何を見てもピントが合いません。照明を点けたまま寝落ちしてしまう事がしばしばあり、それも悪化を助長しているのかも知れません。錐体細胞は受光すると休みっぱなしになるらしいですからねえ。

そんな訳でディスプレイも暗めにしてエディタも暗い色調で使っております。以下の記事を参考にしました。

Emacs は gnome2, vim は evening というテーマが気に入りました。
それでは本日の気になった記事など。