【Python】LINEからYoutubeの曲や動画を落としたい1/3
概要
・【Python】LINEからYoutubeの曲や動画を落としたい1/3
・【Python】LINEからYoutubeの曲や動画を落としたい2/3
・【Python】LINEからYoutubeの曲や動画を落としたい3/3
・docker-composeで実装しています。
・Githubへアップロードしました。
動画でも説明しています。
【Python】Media-Downloader for LINE
経緯について
Androidに曲を落としたいがYoutubeの曲落とすアプリだと広告うざい。
かと言ってWEBから落とせるのもあるが、ずっと変換終わるまで待たないといけない。
もういっそ、自分でアレンジして作ってみようって考えた末、開発に至りました。
本プログラムについて
・Youtube、SoundCloud、ニコニコ動画、Ticktok、Dailymotionに対応しています。
・Youtubeのプレイリストからでも曲、動画の複数ダウンロードに対応しています。
・データはGoogleDrive上に保管されます。
・LINEを閉じようが何しようが、一旦コマンドを送れば自動的に処理が終わります。
・LINE MessageAPIとWebhook、GoogleDriveAPI、Youtube-dlを使用します。
・さくらのVPSサーバを使用しています。
出来上がりの状態
完成後のGIFアニメーション
仕様について
・SoundCloudのURLで間違って動画を取得しようとした際は取得できないエラーが発生します。
※ただしプログラムが停止してしまうことはありません。
前提条件
・GoogleDriveAPI(GCPを使用)が使用できること。参考にした記事
・LINE MessageAPIが使用できること。参考
・ngrokが利用できること。参考にした記事
・Pythonの基礎知識があること。(なくてもほぼコピペで動くようには書くつもり)
動作環境
・Python 3.8.4 (3系なら動く)
・CentOS Linux release 7.8.2003 (Core) (7系ならOK)
・ngrok version 2.3.35
・pip 20.1.1
・line-bot-sdk 1.16.0
・google-api-python-client 1.9.3
・PyDrive 1.3.1
・youtube-dl 2020.06.16.1
・Flask 1.1.2
・ffmpeg 3.4.8
・httplib 0.15.0(推奨)0.15以上だとGBを超えるファイルで以下のエラーが出ます。
・httplib 0.15.0 (最新の0.16.0では大きい動画だとGoogleDriveへアップロード時に以下のエラーが出ます)
Redirected but the response is missing a Location: header.
詳細はこちら
2020/07/22 0.18.1が来てました。こちらでは問題なく動いたようです。
ディレクトリ構造
$HOME/
┝ line/
┝ app.py
┝ youtube.py
┝ start.sh
┝ credentials.json
┝ settings.yaml
┕ youtube/
┕ sound.mp3,movie.mp4
実装に必要なライブラリ等のインストール
# pip install line-bot-sdk
# pip install google-api-python-client
# pip install PyDrive
# pip install youtube-dl
//最新にアップデート推奨
# pip install -U httplib
以下から一般ユーザーで作成しています。
ディレクトリ作成
$ mkdir $HOME/line/youtube
$ cd $HOME/line
では早速、youtube-dlのプログラムから作成していきます。
オプション設定についてはこちらをご参考ください。
youtube.pyの作成
$ vim youtube.py
#!/bin/env python3
import youtube_dl
import sys
import os
import re
from glob import glob
def option_setting(opt,dl_dir):
options = {
'outtmpl':dl_dir + '%(title)s.%(ext)s',
'restrictfilenames':'True',
'quiet':'True',
'default_search':'error'
}
options.update(opt)
return options
def download(option,url):
try:
with youtube_dl.YoutubeDL(option) as ydl: ydl.download([url])
except Exception as e:
return e
def convert(op,files):
ext_dict = {
'.m4a' : ['ffmpeg -y -i "%s" -ab 256k "%s" -loglevel quiet','/mp3'],
'.mp4' : ['ffmpeg -y -i "%s" -ab 256k "%s" -loglevel quiet','/mp3'],
'.webm': ['ffmpeg -y -i "%s" "%s" -loglevel quiet','/mov'],
'.mkv' : ['ffmpeg -y -i "%s" -vcodec copy "%s" -loglevel quiet','/mov'],
}
root, ext = os.path.splitext(files)
formats = ext_dict.get(ext)
if formats != None and formats[1] == op:
if ext != ".mp4" and op == "/mov":
cnv_mp4 = '%s.mp4' % root
cmd = formats[0] % (root+ext, cnv_mp4)
os.system(cmd)
os.remove(root+ext)
else:
cnv_mp3 = '%s.mp3' % root
cmd = formats[0] % (root+ext, cnv_mp3)
os.system(cmd)
os.remove(root+ext)
def main(operation,url,dl_dir):
#ニコニコ動画は変換なし
if "nicovideo" in url:
opt = {}
elif operation == "/mp3":
opt = ({'format':'bestaudio[ext=mp3]/bestaudio[ext=m4a]/bestaudio'})
elif operation == "/mov" or operation == "/nomov":
opt = ({'format':'bestvideo+bestaudio'})
option = option_setting(opt,dl_dir)
msg = download(option,url)
if "retries" in str(msg):
while True:
msg = download(option,url)
if not "retries" in str(msg):
break
if operation == "/mp3" or operation == "/mov":
fileExtensions = [ "mp4", "m4a","mkv","webm"]
files_grabbed = []
for ext in fileExtensions:
files_grabbed.extend(glob(dl_dir + "*." + ext))
for cnv_file in files_grabbed:
convert (operation,cnv_file)
all_file = [f.strip(dl_dir) for f in glob(dl_dir + "*.*")]
# print (all_file)
return all_file
#if __name__ == "__main__":
# dl_dir = "youtube/"
# main("/mp3","https://www.youtube.com/watch?v=9swXEd6SWjA",dl_dir)
下部の4つのコメント部分を外して実際に動くか確認してみるといいです。
フリーBGMの[Shall we meet?.mp3]が取得できればまずは成功です。
※/nomovについては動画変換なしにそのままアップロードする機能です。
今回は一旦ここまでとします。次回はこのyoutube-dlを使ってプログラムを組んでいきます。
Discussion