Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Convert audio track/album to YouTube video


A recipe to prepare audio file(s) for YouTube upload. Video will be a slideshow of images on repeat.

Requires: imagemagick ffmpeg

  1. Convert images to required size. Here I assume .png files and output to png/ folder. See
for f in *.png; do convert "$f" -resize 800x600 -gravity center -background black -extent 800x600 png/"$f".png; done
  1. Generate video out of pngs. Here each image is shown for 20 seconds. See and
ffmpeg -framerate 1/20 -pattern_type glob -i "png/*.png" -c:v libx264 -vf "fps=25,format=yuv420p" png.mp4
  1. Concatenate audio files. See
printf "file '%s'\n" ./*.flac > files.txt
ffmpeg -f concat -safe 0 -i files.txt files.flac
  1. Concatenate png video enough times to cover audio duration. See for rationale.
for i in {1..10}; do printf "file '%s'\n" png.mp4 >> pngs.txt; done
ffmpeg -f concat -safe 0 -i pngs.txt -c copy pngs.mp4
  1. Create YouTube video using acceptable encoding settings. See
ffmpeg -i pngs.mp4 -i files.flac -shortest -codec:v libx264 -crf 21 -bf 2 -flags +cgop -pix_fmt yuv420p -codec:a aac -strict -2 -b:a 384k -r:a 48000 -movflags faststart youtube.mp4
  1. Generate a YouTube track listing to copy-paste in the video description. *.flac
  1. Generate a video file with chapters. *.flac > chapters
ffmpeg -i youtube.mp4 -i chapters -map_metadata 1 -codec copy youtube-chapters.mp4
# Show album track list in ffmpeg metadata format
# Only works with .flac atm :-(
# Requires: metaflac sox
round() {
printf "%.${2}f" "${1}"
for f in "$@"
start=$(round $offset 0)
echo "[CHAPTER]"
echo "TIMEBASE=1/1000"
echo "START=$start"
delta=$(soxi -D "$f")
offset=$(bc -l <<< "$offset + ($delta * 1000)")
end=$(round $offset 0)
echo "END=$end"
title=$(metaflac "$f" --show-tag=TITLE | sed s/.*=//g)
echo "TITLE=$title"
# Show album track list in YouTube-friendly format including
# clickable track offsets.
# Only works with .flac atm :-(
# Requires: metaflac sox
for f in "$@"
offset=$(date -u -d "0 $start sec" +"%H:%M:%S")
title=$(metaflac "$f" --show-tag=TITLE | sed s/.*=//g)
trackno=$(metaflac "$f" --show-tag=TRACKNUMBER | sed s/.*=//g)
echo "$offset" "$trackno" "$title"
end=$(soxi -D "$f")
start=$(bc -l <<< "$start + $end")
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment