From 57ba077b2bae97d88224f64bddc033c600649a99 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Thu, 5 Jan 2017 13:38:03 +0000
Subject: [PATCH] Add ogg-cover-art

---
 README.md     |   1 +
 ogg-cover-art | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+)
 create mode 100755 ogg-cover-art

diff --git a/README.md b/README.md
index c3be416..1222d8e 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ Here's a list of the most interesting ones, along with what they do and where th
 [tldr-pages](https://github.com/tldr-pages/tldr).
  - [git ignore](https://gitignore.io/) - A really useful subcommand for git that allows you to generate ignore files automagically.
  - organise-photos - A small bash script I wrote that organises the photos in a directory by year & month.
+ - [ogg-cover-art](https://github.com/acabal/scripts/blob/master/ogg-cover-art) - A script that adds cover art to ogg files.
 
 ## Disclaimer
 I don't own many of the tools in this repository. If you are an owner of one of these tools and I haven't linked to you, please let me know as I probably forgot.
diff --git a/ogg-cover-art b/ogg-cover-art
new file mode 100755
index 0000000..d4c3cda
--- /dev/null
+++ b/ogg-cover-art
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+usage(){
+	fmt <<EOF
+DESCRIPTION
+	Add cover art to an OGG file.
+	Adapted from mussync-tools by biapy: https://github.com/biapy/howto.biapy.com/blob/master/various/mussync-tools
+
+USAGE
+	ogg-cover-art [COVER-FILENAME] OGG-FILENAME
+		Add cover art to OGG-FILENAME.  If COVER-FILENAME is not specified, 
+		use cover.jpg, cover.jpeg, or cover.png located in the same folder
+		as OGG-FILENAME.
+EOF
+	exit
+}
+die(){ printf "Error: ${1}\n" 1>&2; exit 1; }
+require(){ command -v $1 > /dev/null 2>&1 || { suggestion=""; if [ ! -z "$2" ]; then suggestion=" $2"; fi; die "$1 is not installed.${suggestion}"; } }
+if [ $# -eq 1 ]; then if [ "$1" = "--help" -o "$1" = "-h" ]; then usage; fi fi
+#End boilerplate
+
+require "vorbiscomment" "Try: apt-get install vorbis-tools"
+
+if [ $# -eq 0 ]; then
+	usage
+fi
+
+outputFile=""
+imagePath=""
+
+if [ $# -eq 1 ]; then
+	outputFile="$1"
+	dirName=$(dirname "$1")
+	imagePath="${dirName}/cover.jpg"
+	if [ ! -f "${imagePath}" ]; then
+		imagePath="${dirName}/cover.jpeg"
+		if [ ! -f "${imagePath}" ]; then
+			imagePath="${dirName}/cover.png"
+			if [ ! -f "${imagePath}" ]; then
+				die "Couldn't find a cover image in ${dirName}."
+			fi
+		fi
+	fi
+fi
+
+if [ $# -eq 2 ]; then
+	outputFile="$2"
+	imagePath="$1"
+fi
+
+if [ ! -f "${outputFile}" ]; then
+	die "Couldn't find ogg file."
+fi
+
+if [ ! -f "${imagePath}" ]; then
+	die "Couldn't find cover image."
+fi
+
+imageMimeType=$(file -b --mime-type "${imagePath}")
+
+if [ "${imageMimeType}" != "image/jpeg" -a "${imageMimeType}" != "image/png" ]; then
+	die "Cover image isn't a jpg or png image."
+fi
+
+oggMimeType=$(file -b --mime-type "${outputFile}")
+
+if [ "${oggMimeType}" != "audio/x-vorbis+ogg" -a "${oggMimeType}" != "audio/ogg" ]; then
+	die "Input file isn't an ogg file."
+fi
+
+#Export existing comments to file
+commentsPath="$(mktemp -t "tmp.XXXXXXXXXX")"
+vorbiscomment --list --raw "${outputFile}" > "${commentsPath}"
+
+#Remove existing images
+sed -i -e '/^metadata_block_picture/d' "${commentsPath}"
+
+#Insert cover image from file
+
+#metadata_block_picture format
+#See: https://xiph.org/flac/format.html#metadata_block_picture
+imageWithHeader="$(mktemp -t "tmp.XXXXXXXXXX")"
+description=""
+
+#Reset cache file
+echo -n "" > "${imageWithHeader}"
+
+#Picture type <32>
+printf "0: %.8x" 3 | xxd -r -g0 >> "${imageWithHeader}"
+
+#Mime type length <32>
+printf "0: %.8x" $(echo -n "${imageMimeType}" | wc -c) | xxd -r -g0 >> "${imageWithHeader}"
+
+#Mime type (n * 8)
+echo -n "${imageMimeType}" >> "${imageWithHeader}"
+
+#Description length <32>
+printf "0: %.8x" $(echo -n "${description}" | wc -c) | xxd -r -g0 >> "${imageWithHeader}"
+
+#Description (n * 8)
+echo -n "${description}" >> "${imageWithHeader}"
+
+#Picture with <32>
+printf "0: %.8x" 0 | xxd -r -g0  >> "${imageWithHeader}"
+
+#Picture height <32>
+printf "0: %.8x" 0 | xxd -r -g0 >> "${imageWithHeader}"
+
+#Picture color depth <32>
+printf "0: %.8x" 0 | xxd -r -g0 >> "${imageWithHeader}"
+
+#Picture color count <32>
+printf "0: %.8x" 0 | xxd -r -g0 >> "${imageWithHeader}"
+
+#Image file size <32>
+printf "0: %.8x" $(wc -c "${imagePath}" | cut --delimiter=' ' --fields=1) | xxd -r -g0 >> "${imageWithHeader}"
+
+#Image file
+cat "${imagePath}" >> "${imageWithHeader}"
+
+echo "metadata_block_picture=$(base64 --wrap=0 < "${imageWithHeader}")" >> "${commentsPath}"
+
+#Update vorbis file comments
+vorbiscomment --write --raw --commentfile "${commentsPath}" "${outputFile}"
+
+#Delete temp files
+rm "${imageWithHeader}"
+rm "${commentsPath}"
