📚

Raspberry Pi で Youtube の動画を音声に変換して自分専用の Podcast を作成する方法

2023/02/15に公開約4,900字

Youtube は情報収集や知識習得をするのに非常に優秀なプラットフォームです。しかし、ついつい Youtube を見過ぎて時間を浪費することがしばしあります。更に私の場合は Youtube で登録しているチャンネルはほとんど画像を必要とせず、音声のみあれば十分なこと多い。今回は Youtube の動画を音声ファイル (mp3) に変換して、Podcastにする方法を見つけられましたので、その手順をここに記す。

環境

自宅の Raspberry Pi 4 は広告ブロック用サーバーとして運用していてリソースは余っていますので、Raspberry Pi 上にPodcast 環境を構築します。
Linux であれば理論上同じ手順で環境を構築可能です。

uname -a
Linux pi4 5.10.63-v7l+ #1488 SMP Thu Nov 18 16:15:28 GMT 2021 armv7l GNU/Linux

yt-dlp --version
2021.12.01

ffmpeg
ffmpeg version 4.3.3-0+rpt2+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers

caddy version
v2.5.0

ruby --version
ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [arm-linux-gnueabihf]

構築手順

大まかな流れはRaspberry Pi 上で Youtube の登録したチャンネルの動画ダウンロードして、音声ファイルに変換し、Web Server のフォルダに格納する。格納した音声ファイル一覧の RSS を生成し、それを iPhone や任意の端末から Podcast 登録できるようにする。

yt-dlp インストール

以前は [youtube-dl] を使っていましたが、ここ最近メンテされておらず、更にダウンロード時に速度制限がかかります。なので、Youtube ダウンロード用に OSS の [yt-dlp] を用いります。

sudo curl -L [https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp) -o /usr/local/bin/yt-dlp
sudo chmod a+rx /usr/local/bin/yt-dlp

FFmpeg インストール

動画から音声形式に変換するため、[FFmpeg]をインストールします。

sudo apt install ffmpeg

Ruby インストール

Podcast で配信するには音声ファイル以外にRSSファイルが必要です。
RSS を生成するのに Ruby のスクリプト用いるため、Rubyも併せてインストールします。

sudo apt install ruby

Web Server (Caddy) インストール

Podcast公開用の WebServerをインストールします。SSL証明書を自動更新してくれる軽量のCaddyを導入します。必要に合わせてApacheやNginxにしても構いません。

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf '[https://dl.cloudsmith.io/public/caddy/stable/gpg.key](https://dl.cloudsmith.io/public/caddy/stable/gpg.key)' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc
curl -1sLf '[https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt](https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt)' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

動画取得から音声変換の自動化スクリプト

下記一連の処理のシェルスクリプトを作成します。

  1. 動画ダウンロード
  2. 音声変換
  3. RSSファイル作成呼び出し
  4. Webサーバーへ公開フォルダへ格納

podcast.sh

#!/bin/bash
DOC_ROUTE="/var/www/podcast/XX"
WORK_DIR="/home/pi"
HOST_NAME="IP or Domain"
TITLE="XX"

## 取得したいチャンネルのリスト
CHANNELS=("[https://www.youtube.com/c/XXX](https://www.youtube.com/c/XXX)" \
"[https://www.youtube.com/channel/xxx/videos](https://www.youtube.com/channel/xxx/videos)")

## 過去音声ファイルを削除
find $DOC_ROUTE/ -name '*.mp3' -daystart -mtime +14 -delete

## 該当チャンネルの最新3本動画をダウンロード
## 3分以下、60分以上の動画は除外
## すでにダウンロード済みの動画は除外

for CHANNEL in "${CHANNELS[@]}"
do
/usr/local/bin/yt-dlp -x --audio-format mp3 -o "%(channel)s_%(title)s.%(ext)s" --min-filesize 3m --max-filesize 60m --playlist-end 3 --paths $DOC_ROUTE --download-archive archive_fangong $CHANNEL
done

## 特殊文字列を変換
rename 's/\&/\_/' $DOC_ROUTE/*.mp3

## RSSファイル作成
ruby $WORK_DIR/makepodcast.rb $TITLE https://$HOST_NAME/ $DOC_ROUTE > $DOC_ROUTE/index.rss

RSS 生成処理のスクリプトを記述します。

makepodcast.rb

#!/usr/bin/ruby
require 'time'
require 'nkf'

abort "Usage:#{$0} PodcastTitle PublicURL FilesDir" if ARGV.length < 3

title = NKF.nkf('-w', ARGV[0])
location = ARGV[1]
filesDir = ARGV[2]

files = [];
Dir.glob(File.join(filesDir, '*.{mp3,m4a,aac}')) do |path|
name = File.basename(path, File.extname(path))
item = { 'path'   => path,
'name'   => name,
'fname'  => File.basename(path),
'time'   => File.ctime(path),
'length' => File.size(path) }
files << item
end

files = files.sort do |a, b|
a['time'] <=> b['time']
end

puts <<EOS
<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:itunes="[http://www.itunes.com/dtds/podcast-1.0.dtd](http://www.itunes.com/dtds/podcast-1.0.dtd)" version="2.0">
<channel>
<title>#{title}</title>
<itunes:image href="#{location}img.jpg" />
EOS

files.each do |item|
url = location + item['fname']

if (/\.mp3$/ =~ item['fname']) then
mime = 'audio/mp3'
elsif (/\.webm$/ =~ item['fname']) then
mime = 'audio/webm'
else
mime = 'audio/mp4'
end

puts <<-EOS
<item>
<title>#{item['name']}</title>
<enclosure url="#{url}"
length="#{item['length']}"
type="#{mime}" />
<guid isPermaLink="true">#{url}</guid>
<pubDate>#{item['time'].rfc822}</pubDate>
</item>
EOS
end

puts <<EOS
</channel>
</rss>
EOS

Web Server 設定(Caddy)

Web公開できるようにCaddyファイルを編集する。

  • /etc/caddy/Caddyfile
domain or ip {
root * /var/www/podcast/xx/
file_server {
browse
hide *.part *.webm
}
}

Crontab 設定

定期的に動画をダウンロードするように、Crontab を記述します。

podcast

00 * * * * /bin/bash /home/pi/podcast_xx.sh > /var/log/podcast-xx.log 2>&1

アクセス方法

iPhone の Podcast アプリから ライブラリ > 番組 > ・・・ > 番組をURLで追加 で RSS ファイルのURLを登録します。

最後に

これで Youtube アプリを開き、動画を選択しなくても快適にコンテンツを楽しめるようになります。また、あの煩わしい Youtube 広告ともおさらばできます。自宅に余っているサーバーがあれば試してみてはいかがでしょうか。

参考

[https://qiita.com/tinoji/items/5f57239de5772681c64a]

追記

Raspberry Pi の SDカードには寿命がありますので、音声ファイルは外付け HDD に格納することをおすすめします。

Discussion

ログインするとコメントできます