Help us understand the problem. What is going on with this article?

Youtubeからmp3やmp4をダウンロードする。(コード提供)

1. はじめに

【2019/8/10 23:22】KeyError's'について追記。(一番下)

1.1 経緯

気象庁のスクレイピングをしてからのこと、統計データやビックデータをスクレイピング、そして統計解析することにハマってしまいました...orz
Twitterは利用規約に違反しそうになるのでここでは取り上げません。このサイトを見ればわかります。FaceBookも同様の理由で取り上げません。本名ですし。しかし、Youtubeについては(僕の身の)安全(を確保できるかんじ)でしたので載せてもいいかなと。

1.2 こんな感じ(読んだほうがいい)

Pythonには誰かが作ったpytubeってのがあります。これでダウンロードができます。
Youtubeには様々な形式バージョンでアップロードされています。音声付き動画(普通のやつ)、動画のみ、音声のみの3種です。その中でも画質、フレームレート、音の精度などあるのでバージョンは10個ほどあります。それぞれにタグというものがついているのでそれを指定してダウンロードしますが動画ごとにタグもバージョンの種類も違うので一回一回ユーザーの選択が必要です。規則性はほとんどないですが、音声のファイルで最もいいものは140番のタグだという決まりがあるそうです。

さらに言うと、音声付き動画のは画質が悪い場合が多いです。あと、音声のみのファイルでもmp4で出てきます。今回は以下の機能を付けました。

  • 動画のみのダウンロード(mp4)
  • 音声のみのダウンロード(ちゃんとmp3にします)
  • 音声付き動画(mp4)
  • 動画のみと音声を合成する(mp4)

一般的には最後の機能を使います。なぜなら、三つ目の機能だと画質が悪いからです。

mp4から音声部分のみ取り出すのと合成は両方、ffmpegの機能が使えます。pytubeと一緒にダウンロードしましょう。

$ pip install pytube
$ pip install ffmpeg

2.実装

完成
# やってなかったらやる↓
# pip install pytube
# pip install ffmpeg

# import
from pytube import YouTube
import subprocess
import os
import glob
from google.colab import files

# tag140(audio/mp4だけど動画なし)をダウンロードして動画と音声を引きはがす
def MakeMp3FromTag(yt):
  # musicディレクトリにダウンロード
  yt.streams.get_by_itag(140).download(r"music/")
  # mp4は一つだけのはず
  dir = glob.glob("music/*.mp4")
  # 列挙する(一つだけど)
  name = [n.split('.')[0] for n in dir]
  # 引きはがすコマンドを生成
  cmd = 'ffmpeg -i \"{0}.mp4\" \"{0}.mp3\"'.format(name[0])
  #cmd_list = ["ffmpeg", "-i", "\"{0}.mp4\"".format(name[0]), "\"{0}.mp3\"".format(name[0])]
  # 実行
  subprocess.call(cmd, shell=True)
  # mp4は削除(mp3しか残らない)
  os.remove(name[0]+".mp4")
  # パスを返す
  return name[0]

# 足りないディレクトリを生成
if not os.path.exists('music'):
    os.mkdir('music')

if not os.path.exists('video'):
    os.mkdir('video')

if not os.path.exists('mix'):
    os.mkdir('mix')

# urlを入力させる
url = input('>> Prease enter URL : ')
# タイプを入力させる
types = input('>> Press enter TYPE (Video(only) , Music(only) , Mix , Make) : ')
# 解析
yt = YouTube(url)

if types == "Video":
  # Videoのみのタグを列挙
  for lis in yt.streams.filter(type='video').all():
    print(lis)
  # タグを入力させる
  tag = input('>> Prease enter itag :')
  # videoディレクトリに生成
  yt.streams.get_by_itag(int(tag)).download(r"video/")
  # GoogleColaboからダウンロード
  files.download("video/" + yt.title + ".mp4")

if types == "Music":
  # 呼ぶ
  title = MakeMp3FromTag(yt)
  # GoogleColaboからダウンロード
  files.download(title+".mp3")

if types == "Mix":
  # 音声入りの動画のタグを列挙
  for lis in yt.streams.filter(progressive=True).all():
    print(lis)
  # タグを入力させる
  tag = input('>> Prease enter itag :')
  # mixディレクトリにダウンロード
  yt.streams.get_by_itag(int(tag)).download(r"mix/")
  # GoogleColabからダウンロード
  files.download("mix/" + yt.title + ".mp4")

if types == "Make":
  # Videoのみのタグを列挙
  for lis in yt.streams.filter(type='video').all():
    print(lis)
  # タグを入力させる
  tag_1 = input('>> Prease enter video itag :')
  # videoディレクトリにダウンロード
  yt.streams.get_by_itag(int(tag)).download(r"video/")
  # タイトルは保存
  video_title = yt.title

  # mp3を生成
  MakeMp3FromTag(yt)
  # コマンドを生成 (homeディレクトリに試作版と少し名前を変えてくっつける)
  cmd = "ffmpeg -i \"video/{0}.mp4\" -i \"music/{0}.mp3\" -map 0:0 -map 1:0 \"{0}(制作版).mp4\"".format(video_title)
  # コマンドを実行
  subprocess.call(cmd, shell=True)
  # 使ったやつは削除
  os.remove("video/{0}.mp4".format(video_title))
  os.remove("music/{0}.mp3".format(video_title))
  # GoogleColabからダウンロード
  files.download("{0}(制作版).mp4".format(video_title))

コメントを入れているので大丈夫だと思います。
GoogleColabからダウンロードする処理は消してもらって構いません。

3.まとめ

今回は解説がすくないですがご了承ください。かなり忙しくなってしまいました。ダウンロード速度は既存のサイトより遅いですが自分で高画質のやつを作れたりとかなり高性能だと思います。次からはこれでYoutubeから動画をダウンロードしたいですねw

Twitter: https://twitter.com/Cyber_Hacnosuke (フォローしてくださいお願いします。)
Github: https://github.com/CyberHacnoshuke

Pytubeがエラーを吐いて使えないときの対処法

バージョンを上げるか、Githubから直接ダウンロードしてください。
めんどくさい人はこちらの記事を見てください。詳細もあります。
https://qiita.com/Cyber_Hacnosuke/items/5b9975fac90d1be17e6b

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away