Search code examples
bashffmpegyoutube-dl

Adding mp3 metadata with space in ffmpeg using bash


I have this bash script on downloading youtube videos then convert it to mp3 using youtube-dl and ffmpeg.

#!/bin/bash

ytlink=""
outputFileName=""
title=""
artist=""
album=""

while getopts l:o:t:r:b: flag; do
  case "${flag}" in
    l) ytlink="${OPTARG}";;
    o) outputFileName="${OPTARG}";;
    t) title="${OPTARG}";;
    r) artist="${OPTARG}";;
    b) album="${OPTARG}";;
  esac
done

youtube-dl "$ytlink" --add-metadata --extract-audio --audio-format mp3 --output "temp.%(ext)s"

tempFilename="temp.mp3"
outputFileName="$outputFileName.mp3"

args+=("-i" "$tempFilename" "-metadata" "title='$title'" "-metadata" "artist='$artist'" "-metadata" "album='$album'" "-metadata" "comment=Source:$ytlink")
ffmpeg -loglevel debug ${args[@]} -acodec copy "$outputFileName"
rm "$tempFilename"

This script is fine if I have one word title/artist/album. However, if I have a space, ffmpeg interprets each word before space as another parameter. This is how I use this on command line:

./yttomp3.sh -l "https://www.youtube.com/watch?v=KwQnSHAilOQ" -o "Lee - Autumn Day" -t "Autumn Day" -r "Lee" -b "(Free) Lo-fi Type Beat - Autumn Day"

The debug output of ffmpeg:

Splitting the commandline.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'.
Reading option '-i' ... matched as input url with argument 'temp.mp3'.
Reading option '-metadata' ... matched as option 'metadata' (add metadata) with argument 'title='Autumn'.
Reading option 'Day'' ... matched as output url.
Reading option '-metadata' ... matched as option 'metadata' (add metadata) with argument 'artist='Lee''.
Reading option '-metadata' ... matched as option 'metadata' (add metadata) with argument 'album='(Free)'.
Reading option 'Lo-fi' ... matched as output url.
Reading option 'Type' ... matched as output url.
Reading option 'Beat' ... matched as output url.
Reading option '-' ... matched as output url.
Reading option 'Autumn' ... matched as output url.
Reading option 'Day'' ... matched as output url.
Reading option '-metadata' ... matched as option 'metadata' (add metadata) with argument 'comment=Source:https://www.youtube.com/watch?v=KwQnSHAilOQ'.
Reading option '-acodec' ... matched as option 'acodec' (force audio codec ('copy' to copy stream)) with argument 'copy'.
Reading option 'Lee - Autumn Day.mp3' ... matched as output url.
Finished splitting the commandline.

I tried enclosing the arguments to quotes on the script but it's still not working. How should I deal with this? Thanks.


Solution

  • You are going through royal pains to contruct an array and meticulously quoting all your strings ... And then you don't quote the array.

    You want double quotes around "${args[@]}"