Sharing a script I wrote for a music player-like program that randomly plays music with VLC in Windows 10 WSL Linux bash.
I wrote it on a whim. It could probably work without VLC too. Well, I only use VLC anyway.
Tool to Randomly Play Music Files with VLC
This script is for randomly playing music files in a specified directory and works in the WSL (Windows Subsystem for Linux) Bash environment. Below, I’ll explain the main parts of the script and their operation step by step.
shufmusic(){
: Play randomized music on current directory with vlc.exe. compatible with wsl bash.
: e.g. shufmusic
: e.g. shufmusic mp4
# Create a list of music files and save to list.txt
# List files with extensions wav, mp3, flac, wave
[[ "${1}" =~ mp4|video ]] && find -L -regextype posix-extended -regex '.*\.(wav|mp3|flac|wave|mp4|avi)' > shufmusic_list.tmp.txt || find -L -regextype posix-extended -regex '.*\.(wav|mp3|flac|wave)' > shufmusic_list.tmp.txt
# Confirm the list file is not empty
[ -s shufmusic_list.tmp.txt ] || { printf "\n\n${red}E: The list file empty. It's seems something worng.${end}\nINFO: You may have to use ${cyn}shufmusic mp4${end}.\n\n" ; return 1 ; }
printf "INFO: $(wc -l shufmusic_list.tmp.txt | awk '{print $1}') files found.\n"
# Main loop
while [ true ];
do
sleep 1
# If the list file is not empty, randomly select a song
[ -s shufmusic_list.tmp.txt ] && currentMusic="$(cat shufmusic_list.tmp.txt | shuf | head -n 1)" || { printf "\n\n${red}E: The list file is being empty.${end}\n\n" ; return 1 ; }
# Confirm currentMusic is not empty
[ -z "${currentMusic}" ] && { printf "\n\n${red}E: \$currentMusic is empty.${end}\n\n" ; return 1 ; }
# Delete the selected song from the list
perl -i -pe "BEGIN{undef $/;} s/$(printf "%q" "$currentMusic" | sed -Ee 's/\//\\\//g')\n//smg" shufmusic_list.tmp.txt
# Play the song using vlc.exe
vlc.exe "$(wslpath -w "$(realpath "${currentMusic}")")" &
# Wait for a certain time according to the song length
[[ "${currentMusic##*.}" =~ mp4|avi ]] && sleep "$(ffprobe -i "${currentMusic}" -show_entries format=duration -v quiet -of csv="p=0")" || sleep "$(sox --info -D "${currentMusic}")"
sleep 1
done
}
This script is for playing music files in a specified directory, explained in the following steps:
-
Using the
findcommand, generate a list of music files (.wav, .mp3, .flac, .wave) and save it toshufmusic_list.tmp.txt. This list is used for random playback. If$1(the first argument passed to the script) ismp4orvideo, mp4 and avi files are also added to the list. -
Check if the list file is not empty; if it is empty, output an error message and exit the script.
-
The main loop begins, set up as an infinite loop.
-
Inside the loop, there’s a 1-second break.
-
If the list file is not empty, randomly select a song and store it in
currentMusic. -
Confirm that
currentMusicis not empty; if it is empty, output an error message and exit the script. -
Delete the filename contained in
currentMusicfrom the list file and play that song. -
Depending on the song format, get the playback time with
ffprobe(for mp4 or avi) orsox(for other formats) and wait for the corresponding duration. -
Finally, there’s a 1-second break before moving to the next song.
Installing Additional Packages
To run this Bash script, several external packages and tools are required. Here’s an explanation of those packages:
-
vlc.exe:- VLC Media Player is a famous media player application used for playing music and video files. This script uses
vlc.exeto play music files.vlc.exeis typically the Windows version of VLC Media Player. You need to install this application and add it to your PATH.
- VLC Media Player is a famous media player application used for playing music and video files. This script uses
-
find:- The
findcommand is used to search for files in a specified directory. In this script, it’s used to find music files with specific extensions. Generally, you can install thefindcommand using a Linux distribution (or package manager provided within WSL). For example, on Ubuntu, you can install it with a command likesudo apt-get install findutils.
- The
-
shuf:- The
shufcommand is used to randomly rearrange lines in a text file. This script usesshufto randomly select songs from the music file list.shufis generally included in Linux distributions and doesn’t require additional installation.
- The
-
wslpath:- The
wslpathcommand is used to convert between Windows paths and Linux paths. This script useswslpathto convert Windows paths to Linux paths to pass tovlc.exe.wslpathis a utility provided within WSL and is usually automatically available when you install WSL.
- The
-
realpath:- The
realpathcommand is used to get the absolute path of a specified file. This script usesrealpathto get the absolute path ofcurrentMusic.realpathis generally included in Linux distributions and doesn’t require additional installation.
- The
-
ffprobe:ffprobeis part of the FFmpeg project and is a command used to get properties and metadata information of video and audio files. This script usesffprobeto get the playback time of mp4 or avi files.ffprobeis usually provided with FFmpeg. When you install FFmpeg,ffprobebecomes available.
-
sox:soxis a command-line tool for processing and manipulating audio files. This script usessoxto get the playback time of music files.soxcan be installed through Linux distributions. For example, on Ubuntu, you can install it with a command likesudo apt-get install sox.
By installing these tools and packages and adding them to your PATH, you should be able to run this script normally. In particular, make sure vlc.exe, find, shuf, and wslpath are added to the PATH environment variable.
Summary
Even though I made it myself, it’s quite convenient. When you discover a good song, you just cd to the folder with the file and run this to randomly play it, so it’s perfect for the “I just want to play some music” demand. VLC also has a playlist function, but drag-and-drop is tedious, and FLAC is heavy. With this command, if you run it in a directory with symbolic links, you can easily randomly play even tens of thousands of high-resolution files. Nice.
I’ll upload code updates to github or .bashrc when there are updates.