#!/bin/bash
IFS=
+ IFS=
set -vx
+ set -vx
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <input_directory> <target_directory>"
exit 1
fi
+ '[' 2 -ne 2 ']'
INPUT_DIR="$1"
+ INPUT_DIR=/tank/mp3/#TOCONVERT_2_128CBR/TEST
TARGET_DIR="$2"
+ TARGET_DIR=/tank/mp3/#CONVERTED_2_128CBR
INPUT_DIR="${INPUT_DIR%/}"
+ INPUT_DIR=/tank/mp3/#TOCONVERT_2_128CBR/TEST
TARGET_DIR="${TARGET_DIR%/}"
+ TARGET_DIR=/tank/mp3/#CONVERTED_2_128CBR
TEMPIMAGEFILE="myEmbeddedImage.jpg"
+ TEMPIMAGEFILE=myEmbeddedImage.jpg
check_if_running() {
local script_fullpath
script_fullpath="$(basename "$0")" # Canonical path to this script
local matching_pids
echo "* checking if another instance is active...."
matching_pids="$(pgrep -f "$script_fullpath")"
local count
count="$(echo "$matching_pids" | wc -l)"
if [[ "$count" -gt 1 ]] || ([[ "$count" -eq 1 ]] && [[ "$matching_pids" != "$$" ]]); then
echo "Another instance of $(basename "$script_fullpath") is already running."
exit 1
fi
}
echo ""
+ echo ''
echo ""
+ echo ''
echo ""
+ echo ''
echo "-----------------------------------------------------------------------------"
+ echo -----------------------------------------------------------------------------
echo $0
+ echo /custom/scripte/mp3to128convert.sh
echo ""
+ echo ''
echo "Source dir: $1"
+ echo 'Source dir: /tank/mp3/#TOCONVERT_2_128CBR/TEST'
echo "Target dir: $2"
+ echo 'Target dir: /tank/mp3/#CONVERTED_2_128CBR'
echo "-----------------------------------------------------------------------------"
+ echo -----------------------------------------------------------------------------
check_if_running
+ check_if_running
+ local script_fullpath
++ basename /custom/scripte/mp3to128convert.sh
+ script_fullpath=mp3to128convert.sh
+ local matching_pids
+ echo '* checking if another instance is active....'
++ pgrep -f mp3to128convert.sh
+ matching_pids=1800266
+ local count
++ echo 1800266
++ wc -l
+ count=1
+ [[ 1 -gt 1 ]]
+ [[ 1 -eq 1 ]]
+ [[ 1800266 != \1\8\0\0\2\6\6 ]]
if [ ! -d "$INPUT_DIR" ]; then
echo "Error: Input directory '$INPUT_DIR' does not exist."
echo ""
echo ""
exit 1
fi
+ '[' '!' -d /tank/mp3/#TOCONVERT_2_128CBR/TEST ']'
mkdir -p "$TARGET_DIR"
+ mkdir -p /tank/mp3/#CONVERTED_2_128CBR
SANITIZED_DIR=$(echo "$INPUT_DIR" | sed "s/['\"]/_/g")
++ echo /tank/mp3/#TOCONVERT_2_128CBR/TEST
++ sed 's/['\''"]/_/g'
+ SANITIZED_DIR=/tank/mp3/#TOCONVERT_2_128CBR/TEST
if [ "$INPUT_DIR" != "$SANITIZED_DIR" ]; then
mv "$INPUT_DIR" "$SANITIZED_DIR"
INPUT_DIR="$SANITIZED_DIR"
echo "* renamed directory $INPUT_DIR"
fi
+ '[' /tank/mp3/#TOCONVERT_2_128CBR/TEST '!=' /tank/mp3/#TOCONVERT_2_128CBR/TEST ']'
DIR_NAME=$(basename "$INPUT_DIR")
++ basename /tank/mp3/#TOCONVERT_2_128CBR/TEST
+ DIR_NAME=TEST
OUTPUT_FILE="${TARGET_DIR}/${DIR_NAME}.mp3"
+ OUTPUT_FILE=/tank/mp3/#CONVERTED_2_128CBR/TEST.mp3
echo "* Output filename set to $OUTPUT_FILE"
+ echo '* Output filename set to /tank/mp3/#CONVERTED_2_128CBR/TEST.mp3'
rm -f "$OUTPUT_FILE"
+ rm -f /tank/mp3/#CONVERTED_2_128CBR/TEST.mp3
rm -f "${INPUT_DIR}/${TEMPIMAGEFILE}"
+ rm -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg
COVER_IMAGE=
+ COVER_IMAGE=
TEMP_LIST=$(mktemp)
++ mktemp
+ TEMP_LIST=/tmp/tmp.iDboqi6sHy
rm -f "$OUTPUT_FILE"
+ rm -f /tank/mp3/#CONVERTED_2_128CBR/TEST.mp3
ALL_128_CBR=true
+ ALL_128_CBR=true
while IFS= read -r -d '' myFile; do
safe_file=$(echo "$myFile" | sed "s/['\"]/_/g")
if [ "$myFile" != "$safe_file" ]; then
mv "$myFile" "$safe_file"
fi
if $ALL_128_CBR; then
BITRATE=$(ffprobe -v error -select_streams a:0 -show_entries format=bit_rate -of default=noprint_wrappers=1:nokey=1 "$safe_file")
BITRATE=$((BITRATE / 1000)) # Convert to kbit/s
VBR_DETECTED=$(ffprobe -v error -select_streams a:0 -show_entries format_tags=encoder -of default=noprint_wrappers=1:nokey=1 "$safe_file" | grep -i "VBR")
if [ "$BITRATE" -ne 128 ] || [ -n "$VBR_DETECTED" ]; then
ALL_128_CBR=false
MYTEMPNAME="$(basename "${safe_file}")"
echo "* file has a different bitrate ${BITRATE} kb/s (filename: ${MYTEMPNAME})"
fi
fi
if [[ $safe_file != /* ]]; then
safe_file="/$safe_file"
echo "* had to correct the path of $safe_file ???????"
fi
if [ ! -f "$safe_file" ]; then
echo "* file error: $safe_file"
echo ""
echo ""
echo "ABORT"
echo ""
echo ""
exit 3
fi
echo "file '$safe_file'" >> "$TEMP_LIST"
if [ -z "$COVER_IMAGE" ]; then
VIDEO_PRESENT=$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_type -of csv=p=0 "$safe_file")
if [ "$VIDEO_PRESENT" = "video" ]; then
if ! [ -f "${INPUT_DIR}/${TEMPIMAGEFILE}" ]; then
ffmpeg -y -i "$safe_file" -map 0:v:0 -c copy "${INPUT_DIR}/${TEMPIMAGEFILE}"
if [ -f "${INPUT_DIR}/${TEMPIMAGEFILE}" ]; then
COVER_IMAGE="${INPUT_DIR}/${TEMPIMAGEFILE}"
echo "* Cover picture found - will use this"
fi
fi
fi
fi
done < <(find "$INPUT_DIR" -maxdepth 1 -type f -name "*.mp3" -print0 | sort -z)
+ IFS=
+ read -r -d '' myFile
++ find /tank/mp3/#TOCONVERT_2_128CBR/TEST -maxdepth 1 -type f -name '*.mp3' -print0
++ sort -z
++ echo /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3
++ sed 's/['\''"]/_/g'
+ safe_file=/tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3
+ '[' /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3 '!=' /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3 ']'
+ true
++ ffprobe -v error -select_streams a:0 -show_entries format=bit_rate -of default=noprint_wrappers=1:nokey=1 /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3
+ BITRATE=340469
+ BITRATE=340
++ ffprobe -v error -select_streams a:0 -show_entries format_tags=encoder -of default=noprint_wrappers=1:nokey=1 /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3
++ grep -i VBR
+ VBR_DETECTED=
+ '[' 340 -ne 128 ']'
+ ALL_128_CBR=false
++ basename /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3
+ MYTEMPNAME=1.mp3
+ echo '* file has a different bitrate 340 kb/s (filename: 1.mp3)'
+ [[ /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3 != /* ]]
+ '[' '!' -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3 ']'
+ echo 'file '\''/tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3'\'''
+ '[' -z '' ']'
++ ffprobe -v error -select_streams v:0 -show_entries stream=codec_type -of csv=p=0 /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3
+ VIDEO_PRESENT=video
+ '[' video = video ']'
+ '[' -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg ']'
+ ffmpeg -y -i /tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3 -map 0:v:0 -c copy /tank/mp3/ffmpeg version 5.1.6-0+deb12u1 Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 12 (Debian 12.2.0-14)
configuration: --prefix=/usr --extra-version=0+deb12u1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --disable-sndio --enable-libjxl --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-librav1e --enable-shared
libavutil 57. 28.100 / 57. 28.100
libavcodec 59. 37.100 / 59. 37.100
libavformat 59. 27.100 / 59. 27.100
libavdevice 59. 7.100 / 59. 7.100
libavfilter 8. 44.100 / 8. 44.100
libswscale 6. 7.100 / 6. 7.100
libswresample 4. 7.100 / 4. 7.100
libpostproc 56. 6.100 / 56. 6.100
Input #0, mp3, from '/tank/mp3/#TOCONVERT_2_128CBR/TEST/1.mp3':
Metadata:
date : 2013
Duration: 00:00:43.42, start: 0.025056, bitrate: 340 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
Metadata:
encoder : Lavc57.48
Stream #0:1: Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 800x800 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn (attached pic)
Metadata:
comment : Cover (front)
Output #0, image2, to '/tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg':
Metadata:
date : 2013
encoder : Lavf59.27.100
Stream #0:0: Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 800x800 [SAR 1:1 DAR 1:1], q=2-31, 90k tbr, 90k tbn (attached pic)
Metadata:
comment : Cover (front)
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Press [q] to stop, [?] for help
[image2 @ 0x560f869c86c0] The specified filename '/tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg' does not contain an image sequence pattern or a pattern is invalid.
[image2 @ 0x560f869c86c0] Use a pattern such as %03d for an image sequence or use the -update option (with -frames:v 1 if needed) to write a single image.
frame= 1 fps=0.0 q=-1.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed=0.00798x
video:103kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
+ '[' -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg ']'
+ COVER_IMAGE=/tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg
+ echo '* Cover picture found - will use this'
+ read -r -d '' myFile
++ echo tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3
++ sed 's/['\''"]/_/g'
+ safe_file=tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3
+ '[' tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3 '!=' tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3 ']'
+ false
+ [[ tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3 != /* ]]
+ safe_file=/tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3
+ echo '* had to correct the path of /tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3'
+ '[' '!' -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3 ']'
+ echo 'file '\''/tank/mp3/#TOCONVERT_2_128CBR/TEST/2.mp3'\'''
+ '[' -z /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg ']'
+ IFS=
+ read -r -d '' myFile
++ echo /tank/mp3/#TOCONVERT_2_128CBR/TEST/3.mp3
++ sed 's/['\''"]/_/g'
+ safe_file=/tank/mp3/#TOCONVERT_2_128CBR/TEST/3.mp3
+ '[' /tank/mp3/#TOCONVERT_2_128CBR/TEST/3.mp3 '!=' /tank/mp3/#TOCONVERT_2_128CBR/TEST/3.mp3 ']'
+ false
+ [[ /tank/mp3/#TOCONVERT_2_128CBR/TEST/3.mp3 != /* ]]
+ '[' '!' -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/3.mp3 ']'
+ echo 'file '\''/tank/mp3/#TOCONVERT_2_128CBR/TEST/3.mp3'\'''
+ '[' -z /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg ']'
+ IFS=
+ read -r -d '' myFile
if [ ! -s "$TEMP_LIST" ]; then
echo "Error: No MP3 files found in '$INPUT_DIR'."
rm -f "$TEMP_LIST"
echo ""
echo ""
exit 1
fi
+ '[' '!' -s /tmp/tmp.iDboqi6sHy ']'
if [ -z "$COVER_IMAGE" ]; then
COVER_IMAGE=$(find "$INPUT_DIR" -maxdepth 1 -type f -iname "*.jpg" | head -n 1)
if [ ! -z "$COVER_IMAGE" ]; then
MYTEMPSTRING="$(echo "$COVER_IMAGE" | sed 's#.*/\([^/]\+/[^/]\+\)$#\1#')"
echo "* Using cover image found in directory: $MYTEMPSTRING"
fi
fi
+ '[' -z /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg ']'
echo "start ffmpeg....."
+ echo 'start ffmpeg.....'
echo ""
+ echo ''
echo ""
+ echo ''
if $ALL_128_CBR; then
echo "✅ All files are 128 kbit/s CBR. Merging without re-encoding..."
if [ -n "$COVER_IMAGE" ]; then
ffmpeg -hide_banner -f concat -safe 0 -i "$TEMP_LIST" -i "$COVER_IMAGE" -map 0:a -map 1 -c copy -disposition:v attached_pic \
-id3v2_version 3 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" -y "$OUTPUT_FILE"
else
ffmpeg -hide_banner -f concat -safe 0 -i "$TEMP_LIST" -c copy -y "$OUTPUT_FILE"
fi
else
echo "⚠️ Some files are not 128 kbit/s CBR. Converting to 128 kbit/s..."
if [ -n "$COVER_IMAGE" ]; then
ffmpeg -hide_banner -f concat -safe 0 -i "$TEMP_LIST" \
-i "$COVER_IMAGE" \
-map 0:a -map 1 \
-c:a libmp3lame -b:a 128k\
-c:v copy \
-disposition:v attached_pic \
-metadata:s:v title="Album cover" \
-metadata:s:v comment="Cover (front)" \
-id3v2_version 3 \
-write_id3v1 1 \
-threads 0 \
-y "$OUTPUT_FILE"
#ffmpeg -i "$OUTPUT_FILE" -i "$COVER_IMAGE" -map 0:a -map 1 -c:a copy -disposition:v attached_pic \
# -id3v2_version 3 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" -y "$OUTPUT_FILE"
# ffmpeg -f concat -safe 0 -i "$TEMP_LIST" -i "$COVER_IMAGE" -map 0:a -map 1:v \
# -c:a libmp3lame -b:a 128k -c:v copy -metadata:s:v title="Album cover" \
# -metadata:s:v comment="Cover (front)" -id3v2_version 3 -write_id3v1 1 -y "$OUTPUT_FILE"
else
ffmpeg -hide_banner -f concat -safe 0 -i "$TEMP_LIST" -acodec libmp3lame -b:a 128k -id3v2_version 3 -write_id3v1 1 -y -threads 0 "$OUTPUT_FILE"
fi
fi
+ false
+ echo '⚠️ Some files are not 128 kbit/s CBR. Converting to 128 kbit/s...'
+ '[' -n /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg ']'
+ ffmpeg -hide_banner -f concat -safe 0 -i /tmp/tmp.iDboqi6sHy -i /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg -map 0:a -map 1 -c:a libmp3lame -b:a 128k -c:v copy -disposition:v attached_pic -metadata:s:v 'title=Album cover' -metadata:s:v 'comment=Cover (front)' -id3v2_version 3 -write_id3v1 1 -threads 0 -y /tank/mp3/#CONVERTED_2_128CBR/TEST.mp3
Input #0, concat, from '/tmp/tmp.iDboqi6sHy':
Duration: N/A, start: -0.025056, bitrate: 320 kb/s
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
Metadata:
encoder : Lavc57.48
Stream #0:1: Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 800x800 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn
Metadata:
comment : Cover (front)
Input #1, image2, from '/tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg':
Duration: 00:00:00.04, start: 0.000000, bitrate: 21073 kb/s
Stream #1:0: Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 800x800 [SAR 1:1 DAR 1:1], 25 fps, 25 tbr, 25 tbn
Stream mapping:
Stream #0:0 -> #0:0 (mp3 (mp3float) -> mp3 (libmp3lame))
Stream #1:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
Output #0, mp3, to '/tank/mp3/#CONVERTED_2_128CBR/TEST.mp3':
Metadata:
TSSE : Lavf59.27.100
Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
Metadata:
encoder : Lavc59.37.100 libmp3lame
Stream #0:1: Video: mjpeg (Progressive), yuvj420p(pc, bt470bg/unknown/unknown), 800x800 [SAR 1:1 DAR 1:1], q=2-31, 25 fps, 25 tbr, 25 tbn (attached pic)
Metadata:
title : Album cover
comment : Cover (front)
frame= 1 fps=0.3 q=-1.0 Lsize= 2149kB time=00:02:10.94 bitrate= 134.4kbits/s speed=45.8x
video:103kB audio:2045kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.022593%
if [ -f "${INPUT_DIR}/${TEMPIMAGEFILE}" ]; then
rm -f "${INPUT_DIR}/${TEMPIMAGEFILE}"
fi
+ '[' -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg ']'
+ rm -f /tank/mp3/#TOCONVERT_2_128CBR/TEST/myEmbeddedImage.jpg
if [ $? -eq 0 ]; then
# Remove temporary file
rm -f "$TEMP_LIST"
NEW_NAME="$(dirname "$INPUT_DIR")/[CONVERTED] $DIR_NAME"
# mv "$INPUT_DIR" "$NEW_NAME"
echo "✅ Processing complete. Output file: $OUTPUT_FILE"
echo "✅ Renamed directory to: $NEW_NAME"
else
echo "❌ Error: Processing failed!"
fi
+ '[' 0 -eq 0 ']'
+ rm -f /tmp/tmp.iDboqi6sHy
++ dirname /tank/mp3/#TOCONVERT_2_128CBR/TEST
+ NEW_NAME='/tank/mp3/#TOCONVERT_2_128CBR/[CONVERTED] TEST'
+ echo '✅ Processing complete. Output file: /tank/mp3/#CONVERTED_2_128CBR/TEST.mp3'
+ echo '✅ Renamed directory to: /tank/mp3/#TOCONVERT_2_128CBR/[CONVERTED] TEST'