HAVRMの空空活動誌

「空空」は「うつらうつら」と読むらしいです.まぁ常に寝不足なもんで...

ニコニコチャンネル録画について

こんにちは,HAVRMです.

以前タイムシフト録画について記事を書いていました.
havrm.hatenablog.com

一方チャンネルに公開されている動画のダウンロードには昔は開発者タブで見るとMP4のアドレスがあったためそれで直接ダウンロードできていました.
しかし,ある時から,HLSタイプのものが増えてきて(この時はそもそもブラウザで再生できなかったりしましたが...)できなくなりました.
その後ブログで書いたようにタイムシフトもHLSとなり,あらたにShellscriptを組むことで録画をできるようになったので同じようにチャンネルの動画も録画していました.しかし,中には「Invalid Data」と表示されダウンロードできないものもありましたが,タイムシフトで見れるのがほとんどだったのであまり気にしていませんでした.

最近改めて調べていたところ,あるサイトにstreamlinkを使った方法があったので従来のffmpegの方法でエラーが出たときにstreamlinkでダウンロードするコードを作成しました.
なお,streamlinkは

sudo apt-get install streamlink

でインストールすると古いバージョンになるので下のサイトにある方法でインストールします.
streamlink.github.io

sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt update
sudo apt install streamlink

streamlinkを使ったインストールでは特殊なキーが必要となります.このキーが本来のものとffmpegが取得できるキーと異なるためエラーを吐くようです.キーの生成はopensslで行います.
やり方:

  1. m3u8のアドレスをコピーします.開発者タブで”master”を検索すればいいです.これでヒットしない場合は”playlist”と検索すれば出てきます.
  2. 次にキーの内容を取得します.FireFoxの場合,開発者タブで"nv"と"hls"の両方にヒットしたもののレスポンスにある24文字をコピーします.
  3. キーからファイルを生成します.ここではopensslでbase64でデコードした内容をファイル(ここでは"hls.key")に保存します.生成は次のコマンドで行います.
echo <キーの文字列> | openssl enc -d -base64 >hls.key
  1. このキーファイルを使う設定でstreamlinkでダウンロードします.動画のクォリティを選べるので最大の"best"にしておきます.もし,一番悪くしたいときはworst,それ以外の場合はstreamlink実行中に出てくる"Available streams"にあるものを記入すればいいです.例:1080p
streamlink --hls-segment-key-uri file://`pwd`/hls.key <動画のURL> best -o <保存名>

なおここで取得した動画のアドレスはffmpegでダウンロードするときに使うアドレスと同じです.その時のコマンドは次の通りです.

ffmpeg -i <動画のURL> -c copy <保存名>

streamlinkの出力はffmpegと比べ少なく,またteeコマンドで取るとスクリーンへの出力がうまくいかないので,できればffmpegでやりたいです.なのでとりあえずffmpegでダウンロードし,"Invalid Data"のエラーの時にstreamlinkでダウンロードするようプログラムすると次のようになります.

#!/bin/bash
echo "Channel HLS Recorder by HAVRM"
printf "What the URL of NICONICO channel\'s HLS do you want (*master*)? >> "
read HLSURL
CHURL=$(echo $HLSURL | awk -F'/' '{print $6}')
CHURL=${CHURL#*-}
CHURL="https://www.nicovideo.jp/watch/${CHURL%_*}"
TITLE=$(curl ${CHURL} -# | grep "<title>")
TITLE=${TITLE#*>}
echo ${TITLE} | sed -e "s/<\/.*//g" > .title.temp
. clear_datas_exword.sh .title.temp
TITLE=`cat .title.temp`
rm .title.temp
TITLE=$(echo $TITLE | sed -e "s/_-_ニコニコ動画//g")
if [ -z "$TITLE" ]
then
  TITLE="output"
fi
{ ffmpeg -i "$HLSURL" -c copy ${TITLE}.ts 3>&1 1>&2 2>&3 | tee ${TITLE}.txt ; } 3>&1 1>&2 2>&3
if [ `cat -e ${TITLE}.txt | grep Invalid | awk '{print $1}'` ]
then
  echo ""
  echo "HLS downloading by ffmpeg was errored, so streamlink will be used."
  printf "What the key of NICONICO channel\'s HLS do you want (respons of \'nv hls\')? >> "
  read HLSKEY
  echo $HLSKEY | openssl enc -d -base64 >hls.key
  streamlink --hls-segment-key-uri file://`pwd`/hls.key "$HLSURL" best -o ${TITLE}.ts
  rm hls.key
fi
rm ${TITLE}.txt

なおスクリプト中で呼んでいる"clear_datas_exword.sh"は前のブログで紹介したものです.
havrm.hatenablog.com

これで動画のアドレスからタイトルを取得し,ffmpegで試行した後,失敗したら改めてキーの入力を求め,streamlinkでインストールするという動作になります.
自分で運用しているときはffmpegやstreamlinkの出力を読んで様々なデータを取得したり,結果をSlackに送信したりしています(下のブログ参考).
havrm.hatenablog.com

あ,一応これはWSLのUbuntu18.04LTSで動作させています.他のでも動くと思います.

とりあえず最近できるようになったのでまとめました.このstreamlinkはpluginを開発することで様々な動画サイトからダウンロードできるみたいで,AbemaTVのもできるみたい...
あとAndroidで仮想環境が使えるUserLAndでUbuntuとか起動できるからそれでやってもいいかも.(楽天で契約しているけど,うちは楽天圏外だからうまく使えないけど...絶対CM嘘だろ,「全国どこでも」じゃなくて「全国どこかで」だろ...都市圏の中心でしか使えない...それ以外はau回線で月5GBだし...)