📹

学校のタブレットでYoutubeが見れないのでダウンロードできるようにした話 前半

2022/05/11に公開
13

学校のタブレットでyoutubeが見れなくなった

i-fil○erというフィルタリングが導入されて閲覧できるサイトが一気に減ってしまった(禁止されてるサイトを開くと「端末管理者に報告しました」という脅迫文じみたものが表示される)。

校内でスマホの使用は原則禁止なので、配布されるタブレットを使うしかない。

部活が音楽系なのでyoutubeの音源を部活で使用したい時に不便になる(決して授業中にワイヤレスイヤホンをつけて動画を見たいとかではないのである)。

外部サイトも使えない…

youtubeをダウンロードできるサイトはたくさんあるが、フィルタリングのせいで有名どころは対策されてしまっていて使えない。

プロキシサイトはyoutubeが見れるものが残っていたが、動画が開始されるまでに40秒くらいかかり、しかも音が途切れるので使い物にならない。

じゃあ、自分で作ろう

ということで、Node.js + express で簡易的にyoutubeの動画をダウンロードできるapiを作成することにした。
自分で使う用なのでフロントエンドがない

材料

家のサーバーはマイクラでいっぱいなので、外部サービスを組み合わせて無料で構築した。

  • replit
    • オンラインでコードを実行することができるIDE。
  • UptimerRobot
    • replitはページを閉じると、しばらくして実行中のサイトも落ちてしまうため、5分毎にビンタして起こし続ける。
      (2022/10/14追記)netlifyのfunctionsでも少し工夫すれば作れました(APIのレスポンスが6MB?くらいまでなので、動画データを直接ではなくダウンロードリンクを返すことで作れます)。

とりあえず実装

使用するパッケージ

  • express
  • express-stream
  • ytdl-core
    (今回の記事で使用するのはここまで)
  • @ffmpeg-installer/ffmpeg
  • fluent-ffmpeg
  • simple-youtube-api(Youtube APIキーが必要)

① expressを使ってサイトを作る。

const express = require('express');
const stream = require('express-stream');
const app = express();
const ytdl = require('ytdl-core');
const fs = require('fs');
const path = require('path');
const port = 8080;

//次(②)のコードはここに挿入

app.get('/',function(req, res) {
	res.send("Youtube-Downloader")
});
	
app.listen(port, function() {
	console.log(`[NodeJS] Application Listening on Port : ${port}`);
});

② 動画を取得して、ダウンロードする。


app.get('/api/ytdl/:youtubeId',async function(req, res) {
   const { youtubeId } = req.params;
   const destFilePath = path.resolve(__dirname, `./tmp/${youtubeId}.mp4`);
   let info = await ytdl.getInfo(youtubeId);//動画IDから動画の詳細を取得
   if( fs.existsSync(destFilePath) ){//すでに一度ダウンロードしていた場合
      res.download(destFilePath);
      return;
   }
//動画をダウンロード
let stream = ytdl(info.videoDetails.video_url, {filter: (format) => format.container === "mp4"/*フォーマットをmp4指定*/, highWaterMark: 32 * 1024 * 1024, quality: "highest" })
stream.pipe(fs.createWriteStream(destFilePath))

stream.on('error', (err) => {//ダウンロードに失敗した場合
   console.error(err);
   res.status(400).send('download error!');//アクセスしたユーザーにエラーを返す
   return; 
});
stream.on('end', () => {//ダウンロードに成功したら
   console.log(`${youtubeId}.mp4 downloaded.`);
   res.download(destFilePath);//動画ファイルを返す
   return;
  })
})

これで動画ファイルをダウンロードすることができる。

③起動したらウィンドウが出てくるのでボックスにあるURLをコピー(赤部分)

UptimerRobotを開いて、+Monitorを押す。

Monitor TypeHTTP(s)にして③のURLを貼る。

下にスクロールしてCreate Monitorを押して完了!

https://リポジトリ名.ユーザー名.repl.co/api/ytdl/動画のIDでダウンロードできる。(初回のダウンロードには少々時間がかかる)

まとめ

今回はmp4形式でYoutubeの動画を取得するapiを作った。

このままだとreplitのストレージ上限を超えてしまうので次回はその対策と、ダウンロードされるときのファイル名がIDのままなので動画のタイトルに変更する。

後半↓
https://zenn.dev/aiueokashi/articles/6f8de4b42806e5

Discussion

dkdk

僕ができていたのはinvidiousフォートナイトですかね
でも僕の学校は規制かかってしまいました

dkdk

スライドの挿入を押して動画を開くとできました