#前置き
YouTube-dl使ってYouTubeの動画をmp4にしたくありませんか?
今回はYouTube-dlを使った時に直面した問題について書きたいと思います。
ただしこの記事ではYoutube-dlの導入方法は記述しないので各自調べてください。
#YouTube-dlとは
YouTube-dlは簡単に言うとYouTubeなどからの動画をmp4やmp3にすることができるコマンドラインプログラムです。
コマンドラインプログラムからわかるようにYouTube-dlはコマンドで一括で実行するものです。
でもスクリプトで記述したくありませんか?
そこでスクリプトで記述しました。
#スクリプト(問題解決前)
まず本来の書き方はこうです。
youtube-dl [OPTIONS] YouTube動画のURL [URL...]
これをコマンドラインで記述すると動きます。
ではここで問題が起こったときのスクリプトを見ましょう
import youtube_dl
ydlmp4 = youtube_dl.YoutubeDL({'outtmpl': '[出力時のファイル名]','format':'bestvideo[ext=mp4]+bestaudio'})
ydlmp4.extract_info(
[YoutubeのURL],
download=True
)
これです。ちなみにこれでもちゃんと動画はダウンロードはできます。
しかし
bestvideo[ext=mp4]+bestaudio'
この部分の[ext=mp4]というでmp4に設定しているのですがなぜかわかりませんがmp4ではなくmkvなどのmp4ではないファイナルで出力されてしまいます。
ただここで拡張子をmp4に変えるやり方もあるのですがあまり気分のいいものではないので使わないこととして
ここでこの問題に対する解決策を考えました。
#スクリプト(問題解決後)
ここでこの問題を解決するのに必要なのは
・ffmpeg
・moviepy.editor
がとても重要になってきます。
これを使ってスクリプトを記述します。
import youtube_dl
import moviepy.editor as mp
import os
import ffmpeg
#動画の出力
ydlmp4 = youtube_dl.YoutubeDL({'outtmpl': '[出力時のファイル名]','format':'bestvideo'})
ydlmp4.extract_info(
[YouTubeのURL],
download=True
)
#音声の出力
ydl_opts = {
'format': 'bestaudio/best',
'outtmpl': '[出力時のファイル名]' + '.%(ext)s',
'postprocessors': [
{'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192'},
{'key': 'FFmpegMetadata'},
],
}
ydlmp3 = youtube_dl.YoutubeDL(ydl_opts)
info_dict = ydlmp3.extract_info('[mp4で出力した時と同じYouTubeのURL]', download=True)
#mp4として出力されてものに.mp4を付ける
os.rename([出力時のファイル名], "[出力時のファイル名].mp4")
#映像と音声を合わせる
clip = mp.VideoFileClip('[出力時のファイル名].mp4').subclip()
clip.write_videofile('[mp4として出力されたファイル]', audio='[mp3として出力されたファイル]')
このスクリプトの説明をしたいと思います。
まず動画の出力のところ
先ほど言った[ext=mp4]で出力できないという問題に対して映像のみを出力するようにしました。この場合拡張子が何もついてない状態となります。ここでmp4の拡張子を付け足すことで音声のない映像となります。(gifみたいなものですね)
そして音声出力のところ
流石に音声がないといやなのでffmpegを使って音声を出力します。ここではちゃんとmp3の出力の設定をしとけばちゃんと動きます。
そして2つを合わせて出力する。
この動作はmoviepy.editorを使用しています。
これでできた動画はほぼ音声と映像との誤差がないのでほぼ完ぺきに出力されると思います。
#結論
とりあえずスクリプトで記述するならばこういう方法もあると思いますので、もしやってみたいという方は参考にしてみてください。
ただ注意してほしいのはちゃんと著作権には気をつけてください。それらに関しては一切の責任を負いません。