【Python】LINE에서 Youtube의 노래나 동영상을 떨어뜨리고 싶은 1/3

개요



· 【Python】LINE에서 Youtube의 노래나 동영상을 떨어뜨리고 싶은 1/3
· 【Python】LINE에서 Youtube의 노래나 동영상을 떨어뜨리고 싶은 2/3
· 【Python】LINE에서 Youtube의 노래나 동영상을 떨어뜨리고 싶은 3/3

GitHub 에 업로드했습니다.

・Zenn의 기사가 최신입니다.
htps : // 전. 에서 v / t s d_d m / r c / s / 6f b229fb71216

경위에 대해서



안드로이드에 노래를 떨어뜨리고 싶지만 Youtube의 곡락하는 앱이라고 광고 까다로운.
그렇다고 WEB에서 떨어뜨리는 것도 있지만, 계속 변환이 끝날 때까지 기다려야 한다.
이제 차라리, 스스로 어레인지해 만들어 보려고 생각한 끝, 개발에 이르렀습니다.

본 프로그램에 대하여



・Youtube의 곡, SoundCloud, 니코니코 동영상에 대응하고 있습니다.
・Youtube의 플레이리스트에서도 곡, 동영상의 복수 다운로드에 대응하고 있습니다.
· 데이터는 GoogleDrive에 저장됩니다.
・LINE을 닫으려고 하지만, 일단 커맨드를 보내면 자동으로 처리가 끝납니다.
· LINE MessageAPI와 Webhook, GoogleDriveAPI, Youtube-dl을 사용합니다.
· 사쿠라 VPS 서버를 사용하고 있습니다.

완성 상태





사양에 대해



· SoundCloud URL에서 잘못 동영상을 가져오려고 하면 검색할 수 없는 오류가 발생합니다.
※단 프로그램이 정지해 버리는 일은 없습니다.

전제 조건



· GoogleDriveAPI (GCP 사용) 을 사용할 수 있는 것. 참고한 기사
· LINE MessageAPI 을 사용할 수 있는 것. 참고
ngrok 을 이용할 수 있는 것. 참고한 기사
· 파이썬의 기초 지식이 있음. (없이도 거의 copipe로 움직이려면 쓸 것)

운영 환경



・Python 3.8.4 (3계라면 움직인다)
· CentOS Linux release 7.8.2003 (Core) (7 계열이면 OK)
· ngrok 버전 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.18.1

· 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

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 을 사용해 프로그램을 짜 갑니다.

좋은 웹페이지 즐겨찾기