Skip to content

Instantly share code, notes, and snippets.

@Hecsall
Last active November 3, 2025 00:26
Show Gist options
  • Select an option

  • Save Hecsall/f857b15ef1c97abe489c2c22d16be4c9 to your computer and use it in GitHub Desktop.

Select an option

Save Hecsall/f857b15ef1c97abe489c2c22d16be4c9 to your computer and use it in GitHub Desktop.
m3ugen: A simple function that generates an .m3u8 playlist of songs inside a folder
# M3Ugen
# This function is meant to be inserted inside your .bashrc or .zshrc, then called with
# m3ugen -f path/to/music -n playlistTitle
function m3ugen() {
### - Help text
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]] || [ -z "$1" ]
then
echo ""
echo "M3Ugen"
echo "Create am .m3u8 playlist with all the files contained in the root of the specified directory."
echo "Scanned files: .flac, .mp3, .mp4, .wav, .aac, .ogg, .m4a"
echo ""
echo "Usage:"
echo " `basename $0` -f <music_folder_path>"
echo " `basename $0` -f <music_folder_path> [-n <playlist_title>]"
echo " `basename $0` -f <music_folder_path> [-o <ordering>] [-n <playlist_title>]"
echo ""
echo "Options:"
printf '%-25s %-40s\n' " -h, --help" "Display this message"
printf '%-25s %-40s\n' " -f" "Folder where the songs are"
printf '%-25s %-40s\n' " -o" "Songs order, default: -date"
printf '%-25s %-40s\n' "" "Possible values: date, -date, name, -name"
printf '%-25s %-40s\n' " -n" "Name of the .m3u file but without extension, default: playlist"
return 0
fi
### - Parse parameters
while getopts f:o:n:h option
do
case "$option" in
f) # Songs folder path - required
SONGSPATH=$(echo $OPTARG | sed 's:/*$::') # Remove trailing slash
;;
o) # Songs order - optional
if [[ "$OPTARG" == "name" ]] ||
[[ "$OPTARG" == "-name" ]] ||
[[ "$OPTARG" == "date" ]] ||
[[ "$OPTARG" == "-date" ]]
then
ORDER=$OPTARG
else
echo "\nInvalid value for option -o \nPossible values: \nname, -name, date, -date"
return 0
fi
;;
n)
PLAYLIST_NAME=$OPTARG
;;
*)
echo "Invalid option received, use -h for help."
return
;;
esac
done
### - Check if every parameter is ok
if [ -z "$PLAYLIST_NAME" ]
then
PLAYLIST_NAME="playlist" # Default playlist title if not specified
fi
if [ -z "$SONGSPATH" ]
then
# If missing songs path display error and exit
echo "Missing songs path (-f <your_path>)"
return
fi
if [ -z "$ORDER" ]
then
ORDER="-date" # Default song ordering if not specified
fi
### - Delete old playlist file if exists
if [[ -f "$SONGSPATH"/"$PLAYLIST_NAME".m3u8 ]]; then
rm -f "$SONGSPATH"/"$PLAYLIST_NAME".m3u8
fi
### - Create new .m3u8 file with songs from $SONGSPATH folder
if [[ "$ORDER" == "name" ]]
then
ls -1 "$SONGSPATH" |grep -i -E ".flac$|.mp3$|.mp4$|.wav$|.aac$|.ogg$|.m4a$" > "$SONGSPATH"/"$PLAYLIST_NAME".m3u8
elif [[ "$ORDER" == "-name" ]]
then
ls -r1 "$SONGSPATH" |grep -i -E ".flac$|.mp3$|.mp4$|.wav$|.aac$|.ogg$|.m4a$" > "$SONGSPATH"/"$PLAYLIST_NAME".m3u8
elif [[ "$ORDER" == "date" ]]
then
ls -tr1 "$SONGSPATH" |grep -i -E ".flac$|.mp3$|.mp4$|.wav$|.aac$|.ogg$|.m4a$" > "$SONGSPATH"/"$PLAYLIST_NAME".m3u8
elif [[ "$ORDER" == "-date" ]]
then
ls -t1 "$SONGSPATH" |grep -i -E ".flac$|.mp3$|.mp4$|.wav$|.aac$|.ogg$|.m4a$" > "$SONGSPATH"/"$PLAYLIST_NAME".m3u8
fi
unset SONGSPATH
unset ORDER
unset PLAYLIST_NAME
}
@Hecsall
Copy link
Author

Hecsall commented Dec 6, 2019

Usage:

Display help text:
m3ugen -h

Running
m3ugen -f /music/folder -n playlistName

will create
/music/folder/playlistName.m3u8

containing songs written like this

SongTitle.mp3
AnotherSong.flac
ThatSong.wav
...

The playlist file is meant to be placed inside the same folder where music files are, since song names are basically relative paths to each music file.

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