読者です 読者をやめる 読者になる 読者になる

人生送りバント。

yuki540の人生送りバント。

RubyでAnitubeのダウンロードスクリプトを書く

最近のハマってるお菓子は?

いきなりタイトルの話題とズレますが、私は無類のお菓子好きなため、一つに絞るのが難しいのですが最近ハマっているのは、プリッツ(サラダ)です。

今日もコンビニで2個買って帰りました。

本当はチョコ類が好きなのですが、季節的に溶けやすくなってきたので敬遠気味です。

みなさんの好きなお菓子は何でしょう?

Anitubeをダウンロードする

今まで、anitubeから動画をダウンロードするとき、Chromeデベロッパーツールを開いて、動画をリンクを見つけて、wgetでダウンロードしていたんですが、めんどくさくなったのでスクリプトを書くことにしました。

f:id:yuki540com:20170519215704p:plain

なぜRuby? CoffeeScriptは?

まあ、特に理由はないんですがRubyで書きました。

普段ならCoffeeScriptを使うんですが、気分転換にRubyを使いました。

APIを探せ!

というわけで、作業に取り掛かりましょう。

動画をダウンロードするには動画の直リンクを探さないといけません。

直リンクを探すには、APIを探さないといけません。

探しました。これです。↓

http://www.anitube.se/player/config.php?key={ 動画キー(?) }

動画ページに上記のリンクが入ったscriptタグが埋め込まれています。

curlでリンクにアクセスしてみるとわかるのですが、jwplayerを使ったJavaScriptファイルが返ってきます。

f:id:yuki540com:20170519222624p:plain

その中に…

f:id:yuki540com:20170519222957p:plain

ありますね。動画の直リンク。

ここまで分かれば、あとはコードに落とし込むだけなので簡単ですね。

スクリプトを書く

さあ、コードを書きましょう。

require 'open-uri'

httpリクエストをするので、open-uriをrequireします。

まず、はじめは動画キーとタイトルを取得しましょう。

##
# 動画キー・タイトルの取得
# @param url : 動画URL
# @return { key, title }
##
def get_info(url)
    res    = open url
    status = res.status[0].to_i

    if status == 200
        data = res.read.gsub /(\t|\n)/, ''

        # key
        mat  = data.match /http:\/\/www.anitube.se\/player\/config.php\?key=(.*?)\"/
        key  =  mat[1]

        # title
        data  = data.gsub /\s/, '_'
        mat   = data.match /<title>(.*)<\/title>/
        title = mat[1].sub /_-_AniTube!_Animes_Online/, ''

        return { "key" => key, "title" => title }
    else
        return false
    end
end

まあ、これで多少は大丈夫でしょう。

次は、本命の動画リンクの取得です。

##
# 動画リンクの取得
# @param key : 動画キー
# @return link
##
def get_link(key)
    url    = 'http://www.anitube.se/player/config.php?key=' + key
    res    = open url
    status = res.status[0].to_i

    if status == 200
        files = []
        data  = res.read.gsub /(\t|\n|\s)/, ''
        mat   = data.match /sources:(\[.*?\])/
        mat   = mat[1].scan /file:\"(.*?)\"/
        
        mat.each do |file|
            files.push file[0]
        end
        return files
    else
        return false
    end
end

こちらもさっきと同じように正規表現でマッチさせているだけです。

で、あとはファイルに書き出せば終わり!超簡単!

##
# ファイルの書き込み
# @param title : 動画タイトル
# @param link  : 動画リンク
# @return bool
##
def write(title, link)
    res    = open link
    status = res.status[0].to_i

    if status == 200
        data = res.read
        File.open(title + ".mp4", "w") do |f|
            f.puts data
        end
        return true
    else
        return false
    end
end

GitHubにあげてるよ

今回書いたコードは、GitHubにあげといたのでよかったらみてください。

使い方は、下記の通りです。

ruby anitube.rb 動画URL

YouTube IFrame Player APIをゆるふわにラッピングしてみた。

映画『ノーゲーム・ノーライフ ゼロ』が早く観たい。

f:id:yuki540com:20170514235023j:plain

いやー。ノゲノラの映画楽しみですね。

7/15の上映日まで待てません。あと、魔法科高校の映画も見に行かねば。

ということで、はてなブログを初めて最初の記事は、技術関連です。

最近暑くなってきたので、無理せず、ゆるふわプログラミングで実装しました。

あくまで、ゆるふわ実装なのでそこまで大した機能はありません。

ちょっと便利かなぐらいに感じてもらえれば幸いです。

shuvi-lib

フレームレスなYouTubeプレイヤー「Shuvi」を作った際にYouTube IFrame Player APIを使ったのですが、もうちょっと使いやすくならないかなと思い、自分でゆるふわにラッピングしてみました。

名前は、shuvi-libです。

f:id:yuki540com:20170514233628j:plain

ちなみにShuviは、β版ではありますが公開中です。

f:id:yuki540com:20170514233543p:plain

shuvi-libをプロジェクトへの取り込み

shuvi-libの使う方法はいくつかあります。

一つ目は、GitHubページからダウンロードして自分のプロジェクトに置き、使う方法。

二つ目は、shuvi-libはnpm上で公開されているので、

npm install shuvi-lib

のようにnpmコマンドを使ってプロジェクトに取り込む方法。

三つ目は、私、yuki540のサーバー経由でネットワーク越しにshuvi-libをプロジェクトに取り込む方法です。

<script src="http://api.yuki540.com/shuvi-lib/v1/shuvi.lib.js"></script>

使い方

shuvi-libを使えば、YouTube IFrame Player APIをより簡単に操作することが可能です。

shuvi.lib.jsを取り込み、下記のようにパラメータを渡し、newすれば、すぐにプレイヤーの操作が可能になります。

let shuvi = new Shuvi({
  video_id : ['fQN2WC_Acpg'], // 動画IDの入った配列
  id       : 'player',        // 要素のID
  width    : 500,             // 画面の幅
  height   : 300,             // 画面の高さ
  autoplay : ture             // [option]自動再生(デフォルトは、true)
  loop     : false            // [option]ループ(デフォルトは、false)
})

npm経由の方は、requireを忘れずに。

const Shuvi = require('shuvi-lib')

ここから先は、Methods・Eventsのリファレンスです。

Methods

shuvi-libは、できるだけシンプルでわかりやすいメソッド名にしています。

動画URLから動画IDの取得

video_id = getId(url)

  • [param]url: YouTubeの動画URL
  • [return]video_id: 動画ID

イベントリスナの追加

shuvi.on(event, fn)

  • [param]event: イベント名
  • [param]fn: コールバック関数

プレイリストの変更

shuvi.setPlaylist(playlist)

  • [param]playlist: 動画IDの入った配列

再生

shuvi.play()

停止

shuvi.pause()

次の動画へ

shuvi.next()

後ろの動画へ

shuvi.back()

プレイリスト内の指定の動画を選択

shuvi.select(num)

  • [param]num: プレイリストの番号

ループの有無

shuvi.loop(bool)

  • [param]bool: trueの場合、ループ有。falseの場合、ループ無。

デフォルトは、ループ無です。

再生位置の移動

shuvi.seek(per)

  • [param]per: 0~1の数値

動画の総時間

duration = shuvi.duration()

  • [return]duration: 動画の総時間

現在の再生時間

current = shuvi.current()

  • [return]current: 現在の再生時間

動画の読み込み状況

buffer = shuvi.buffer()

  • [return]buffer: 動画の読み込み具合(0~1)

音量の取得

volume = getVolume()

  • [return]volume: 0~1の値

音量の設定

shuvi.setVolume(volume)

  • [param]volume: 0~1の値

サイズの変更

shuvi.resize(width, height)

  • [param]width: 画面の幅
  • [param]height: 画面の高さ

Events

shuvi-libは、プレイヤーの動作ごと挙動をイベントとして呼び出されます。

  • load
    • 動画の起動読み込み終了時に呼び出されます。
  • error
    • 動画の読み込み・再生の失敗時に呼び出されます。
  • change
    • 動画の変更時に呼び出されます。
    • 初回の動画の時には、発火されません。
  • play
    • 動画再生時に呼び出されます。
  • pause
    • 動作停止時に呼び出されます。
  • seek
    • 動画の再生時間が変更されるたびに呼び出されます。
  • end
    • 動画の再生が終了時に呼び出されます。

おわりに

ぱぱっと書いたものなので、ライブラリとしては物足りない感はありますが、今後、Shuviに取り込む際にアップデートして行こうと思います。

Starください。

Hello, yuki540.

Hello, yuki540.

f:id:yuki540com:20170514170955j:plain

はじめまして。yuki540です。

最近、暑いですね。

暑さしのぎに、北海道バニラを毎日食べてます。

今までQiitaで記事を書いていましたが、はてなにも書いていこうと思います。

技術ネタが多いかもですが、見てくれると幸いです。

Twitter: https://twitter.com/eriri_jp

GitHub: https://github.com/yuki540net