Generate m3u playlistf files for all sub directories within the start folder.

Considers audio files with extensions

  • .aiff
  • .aif
  • .flac
  • .mp3
#!/bin/bash
#===============================================================================
# File:         mkplaylists.sh
# description:  script to create playlist files in directies with audio files
#-------------------------------------------------------------------------------
# settings:     tab width = 4 spaces
#-------------------------------------------------------------------------------
# Copyright:    Copyright Balanced Solutions, 2022
#===============================================================================

#====== Settings ===============================================================

SCRIPT_DIR=`dirname ${0}`
SCRIPT_NAME=`basename ${0}`


AUDIO_FILE_EXTENSIONS=(".mp3" ".flac" ".loss" ".aiff" ".aif")
PLAYLIST_FILENAME_GENERATE="_FROM_FOLDER"
PLAYLIST_DEFAULT_PREFIX=""
PLAYLIST_DEFAULT_FILE_BASENAME="playlist"
PLAYLIST_DEFAULT_EXTENSION="m3u8"

#====== Functions ==============================================================

#--------------------------------------------------------------------------------
# Determines if the provide filename denotes an audio file. Determination whether
# it is an audio is based on a set of known file extensions.
# Params
#   $1 the filename
# Result
#   $?          0 if it appears to be an audio file; 1 if not.
#---------------------------------------------------------------------------------

function isAudioFile(){
    declare filename=$1
    declare extension=".${filename#*.}"

    for audioFileExtension in "${AUDIO_FILE_EXTENSIONS[@]}"
    do
        if [ "${extension}" == "${audioFileExtension}" ] ; then
            return 0
        fi
    done
    return 1
}

#--------------------------------------------------------------------------------
# Compiles an array of filenames in the specified directory which appear to be
# audio files.
# Params
#   $1 the directory to scan
# Returns
#   $?          unspecified
#   __RESULT_00 the playlist as an array of filenames w/o leading path
#---------------------------------------------------------------------------------

function compilePlaylistForDirectory(){

    declare subdir=$1
    declare -a playlist

    for filepath in "${subdir}"/*
    do
        filename=${filepath##*/}
        isAudioFile "${filename}"
        if [ $? -eq 0 ] ; then
            playlist+=("$filename")
            echo "    added ${filename}"
        else
            echo "    skipped ${filename}"
        fi
    done

    __RESULT_00=("${playlist[@]}")
}

#--------------------------------------------------------------------------------
# Scans the provided directory for audio files, and if audio files are found
# a playlist in m3u format is generated and put into the same directory where the
# audio files reside.
# Params
#   $1 the directory to scan
#   $2 shall the folder name be used to create the playlist file name?
#   $3 an optional prefix
# Returns
#   $?          unspecified
#---------------------------------------------------------------------------------

function generatePlaylistForDirectory(){

    declare directory=$1
    declare playlistFileBaseName=$2
    declare playlistPrefix=$3
    declare regeneratePlaylist=$4

    echo "Scanning ${directory}"

    compilePlaylistForDirectory "${directory}"
    declare -a playlist=("${__RESULT_00[@]}")

    declare -i numberOfEntriesInPlaylist=${#playlist[@]}
    if [ ${numberOfEntriesInPlaylist} -eq 0 ] ; then
        echo "    No audio files detected"
        return 1
    fi

    if [ "${playlistFileBaseName}" == "${PLAYLIST_FILENAME_GENERATE}" ] ; then
        playlistFileBaseName=${directory##*/}
    fi

    declare playlistFilename="${playlistPrefix}${playlistFileBaseName}.${PLAYLIST_DEFAULT_EXTENSION}"
    declare playlistFilePath="${directory}"/"${playlistFilename}"

    if [ -f "${playlistFilePath}" ] && [ ${regeneratePlaylist} ] ; then
        echo "    Playlist ${playlistFilename} exists, skipping."
        return
    fi

    for entry in "${playlist[@]}"
    do
        echo ${entry}
    done >"${playlistFilePath}"

    echo "    Playlist ${playlistFilename} generated"
}

#--------------------------------------------------------------------------------
# Traverses the filesystem tree, starting with the provided directory, scans
# for audio files and generates playlists in m3u format in each directory where
# audio files are detected
# Params
#   $1 the directory to scan
# Returns
#   $?          unspecified
#---------------------------------------------------------------------------------

function generatePlaylists(){

    declare startDirectory=$1
    declare playlistFilename=$2
    declare playlistPrefix=$3
    declare regeneratePlaylist=$4

    echo "Generate playlists for folders in ${startDirectory}"
    find "${startDirectory}" -type d |
    while read subdir
    do
        generatePlaylistForDirectory "${subdir}" "${playlistFilename}" "${playlistPrefix}" ${regeneratePlaylist}
    done
}

#--------------------------------------------------------------------------------
# Echos the usage of this script to stdout.
# Returns
#   $?          unspecified
#---------------------------------------------------------------------------------

function printUsage(){
    echo "usage: $SCRIPT_NAME -f <filename> -p <prefix>  -r"
    echo
    echo "  -h             usage infomation"
    echo
    echo "  -f <filename>  By default the script create a playlist named ${PLAYLIST_DEFAULT_PREFIX}${PLAYLIST_DEFAULT_FILE_BASENAME}${PLAYLIST_DEFAULT_EXTENSION}."
    echo "                 With this option you can change the basename from ${PLAYLIST_DEFAULT_FILE_BASENAME} to your needs."
    echo "                 If you specify the literal '_FROM_FOLDER' the script will derive the basename from"
    echo "                 the folder name in which the playlist will be created"
    echo ""
    echo "  -s <directory> By default the script will start scanning the filesystem from the current directory."
    echo "                 With this option you can specify a different start directory"
    echo
    echo "  -r regenerate playlist. By default the script will not overwrite an "
    echo "     existing playlist with the same name"
    echo
}


# -- main ----------------------------------------------------------------------

regeneratePlaylist=false
while getopts "hrp:f:" option; do
    case "${option}" in
        h)  printUsage
            exit 0
            ;;

        f)
            # Regenerate playlist if exists
            regeneratePlaylist=true
            ;;
        o)
            playlistFileName=${OPTARG}
            ;;
        p)
            playlistFilePrefix=${OPTARG}
            ;;

        s)  startDirectory=${OPTARG}
            ;;

        *)  echo "Unsupported option '${option}'"
            printUsage
            exit 1
            ;;
    esac
done

# shift $((OPTIND-1))
startDirectory=${startDirectory:-"."}
playlistFilePrefix=${playlistFilePrefix:-${PLAYLIST_DEFAULT_PREFIX}}
playlistFileName=${playlistFileName:-${PLAYLIST_DEFAULT_FILE_BASENAME}}

generatePlaylists "${startDirectory}" "${playlistFileName}" "${playlistFilePrefix}" ${regeneratePlaylist}
© 2022 Balanced Solutions Contact us
RapidWeaver Icon

Made in RapidWeaver