Podcast配信機能をRailsに組み込んでみた
これは呉高専エンジニア勉強会 Advent Calendar 2017の9日目の記事です。
呉高専OB1年目の@euglena1215です。
今年の12月はすごい勢いで記事書いてます。
とあるラジオのサイトでPodcastを配信したくなったのでどう実現するべきなのかを考えた過程を書いていこうと思います。
コードだけ見たい人はこちら
podcastを配信する仕組みについて
AppleのQ&Aから引用させてもらうと
Can I host my podcast on Apple Podcasts?
No, Apple Podcasts does not host podcasts. You must host media files and RSS feeds on your own web servers or use a third-party host. You can then submit your podcast feed for inclusion in the iTunes Store podcast directory.
What is a podcast feed?
A podcast feed is a URL to an RSS (rich site summary) in XML format. RSS is a technology for announcing updates to a website, and XML is a format for creating content on the Internet.
To publish a podcast on Apple Podcasts, use an Apple Podcast Hosting Partner or create a website that generates a feed conforming to RSS 2.0. When you update the site that hosts your podcast, the RSS feed notifies Apple Podcasts that a new episode is available.
iTunes Connect Resources and Help
とのことです。
ざっくり説明すると Appleではホスティングはしてないよ、何らかの方法でRSSを公開してURLを登録してくれればPodcastとして登録してあげるよ。ってことですね。
ふわっと理解するにはこのページが分かりやすいです。
haruthanatos.wixsite.com
ちなみにTech系Podcastとして有名なrebuildはRSSはこんな感じです。
http://feeds.rebuild.fm/rebuildfm
調査してみる
まずPodcastを配信する方法はなにがあるのかを調べたところ以下を発見しました。
Wordpressのプラグイン
wordpressでぽちぽちすればPodcast配信機能を追加できる。
参考:Podcast番組の作り方・配信方法【WordPressで30分でラジオを始める方法】 – ヒーローズジャーニー
Octopod
Octopod is a set of Jekyll templates, helpers and extensions to deliver your podcasts the cool text file lover's way.
https://github.com/pattex/octopod
設定ファイルをYAMLで書くだけでpodcastのRSSと良い感じのpodcastのページが表示してくれるwebサーバを立てられる
rebuild.fm のrssには <generator>Jekyll</generator>
と書かれてあるのでこれを利用しているっぽい?
dropcaster
With Dropcaster, you simply put the mp3 files into the Public folder of your Dropbox. Then run the Dropcaster script that generates the feed, writing it to a file in your Dropbox, e.g. index.rss. All mp3 files in the Public folder of your Dropbox are already accessible via HTTP, and so will the RSS file. You can then take the RSS file's URL and publish it (again, this is because any file in the Public folder of a Dropbox automatically gets a public, HTTP-accessible URL).
https://github.com/nerab/dropcaster
dropboxにmp3ファイルをアップロードして設定ファイルを作るとrssを自動生成してくれるGem 生成されたrssをレンタルサーバーやS3にアップロードすればpodcastをすぐ配信できるようになる
rss(Ruby標準ライブラリ)
生成されるRSSがpodcast配信に必要なnamespaceに対応していたので頑張れば書けそう
選択してみる
今回の要件としては
wordpressとoctopodはアプリケーションとして完結してしまっていて機能を組み込む余地が少ないのでパス、
dropcasterでdropboxを使わずにRSSを生成することも考えましたがコード読むより作った方が早そうだったのでRuby rssを使って実装することにしました。
設計してみる
擬似コードでやりたいことを表現したらこんな感じです。
日本語で説明するのは苦手なのでやりたいことを察してほしい。。。
# routes.rb Rails.application.routes.draw do # /podcast にGETでアクセスすると # PodcastControllerのindexメソッドの結果を返す get "/podcast", to: "podcast#index" end # podcast_controller.rb class PodcastController < ApplicationController def index rss = if RSSがキャッシュに存在する cached_rss else radios = Radio.published # 公開されているラジオ全件取得 Podcast.Feed.new(radios).generate # podcast用RSSを文字列として出力 end render xml: rss # xml形式のデータとしてrssを出力 end end # radio.rb class Radio < ApplicationRecord # レコードが追加/更新/削除された後実行される after_save :update_rss_cache def update_rss_cache # キャッシュを更新 cached_rss = Podcast.Feed.new(radios).generate end end
RSSを文字列として出力できるモジュールを実装してしまえばpodcastを配信できるイメージが湧いたので実装に移っていきます。
実装してみる
rssのドキュメントとrebuildのrssをにらめっこします。
そしてできたのが
feed.rb, config.rb
です。
Configにプロジェクトに依存しているデータを集め、FeedではRSSを生成する処理に専念できるようにしてます。
initialize
の引数に取っているradioのschemaはこんな感じです。
# == Schema Information # # Table name: radios # # id :integer not null, primary key # title :string(255) not null # description :text(65535) not null # mp3(ファイルパス) :string(255) not null # created_at :datetime not null # updated_at :datetime not null # published_at :datetime # duration(再生時間[sec]) :integer not null # size(バイト数) :integer not null #
複雑なことはしてないのでなんとなく処理の流れはつかめると思います。
PRはこんな感じになりました。
https://github.com/kure-kosen/cho_kure_web/pull/26
テストしてみる
いつか絶対にテストを書くという強い意志は持って日々を過ごしています。
まとめ
少しの実装でPodcast配信機能を実装することができました。
テストはきちんと書きましょう。