Skip to content

Instantly share code, notes, and snippets.

@dmerrick
Last active May 14, 2020 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmerrick/93c6c72bc8a98de5c4bf0007cae16621 to your computer and use it in GitHub Desktop.
Save dmerrick/93c6c72bc8a98de5c4bf0007cae16621 to your computer and use it in GitHub Desktop.

yt-album-combiner

This script is intended to take video a YouTube video and audio from another YouTube video and combine them into a new video.

Dependencies

apt install ffmpeg youtube-dl
#!/usr/bin/env python3
"""
This takes a youtube video and replaces the audio with an album's audio
"""
__author__ = "Dana Merrick"
__version__ = "0.1.0"
__license__ = "MIT"
#TODO: use ffmpeg's minterpolate filter to smooth output
#TODO: use youtube-dl like this
# from __future__ import unicode_literals
# import youtube_dl
# ydl_opts = {}
# with youtube_dl.YoutubeDL(ydl_opts) as ydl:
# ydl.download(['https://www.youtube.com/watch?v=BaW_jenozKc'])
import os
import subprocess
video_id = "yDiD8F9ItX0"
audio_id = "MHf7TimSfrM"
def main():
download_files()
convert_to_mp4()
match_lengths()
combine_files()
cleanup()
def download_files():
video_url = f"https://www.youtube.com/watch?v={video_id}"
audio_url = f"https://www.youtube.com/watch?v={audio_id}"
cmd = f"youtube-dl -k --id -f bestvideo+bestaudio --merge-output-format mkv {video_url}"
print(cmd)
os.system(cmd)
cmd = f"youtube-dl -k --id --extract-audio --audio-format flac --audio-quality 0 {audio_url}"
print(cmd)
os.system(cmd)
def match_lengths():
video_length = video_frame_count()
audio_length = audio_frame_count()
multiplier = audio_length / video_length
warp_video(multiplier)
#TODO: this seems dumb, the only reason I'm doing it is
# because video_frame_count only seems to work with mp4
def convert_to_mp4():
# convert it to mp4, remove audio
cmd = f"ffmpeg -i {video_id}.mkv -c copy -an {video_id}.mp4"
print(cmd)
os.system(cmd)
# get length of video
def video_frame_count():
cmd = f"ffprobe -show_entries stream=duration -of compact -v 0 {video_id}.mp4"
print(cmd)
result = subprocess.run(cmd.split(" "), stdout=subprocess.PIPE)
print(result.stdout)
frames = result.stdout.decode("utf-8").split('=')[-1]
return float(frames)
# get length of audio
def audio_frame_count():
cmd = f"ffprobe -show_entries stream=duration -of compact -v 0 {audio_id}.flac"
print(cmd)
result = subprocess.run(cmd.split(" "), stdout=subprocess.PIPE)
print(result.stdout)
frames = result.stdout.decode("utf-8").split('=')[-1]
return float(frames)
def warp_video(multiplier):
cmd = f"ffmpeg -i {video_id}.mp4 -filter:v 'setpts={multiplier}*PTS' {video_id}-warped.mp4"
print(cmd)
os.system(cmd)
def combine_files():
cmd = f"ffmpeg -i {video_id}-warped.mp4 -i {audio_id}.flac -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 final-output.mp4"
print(cmd)
os.system(cmd)
def cleanup():
cmd = f"rm {video_id}* {audio_id}*"
print(cmd)
os.system(cmd)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment