November 23rd, 2020 – It appears that the cmdmp3 software now plays .wav files. I didn’t do anything special to enable this, so it must pertain to something changing in Windows’ multimedia subsystem.
If the .mp3 functionality works on your machine, you might try playing a .wav. Now, back to the original blog post.
In 2009, I was tinkering with the Windows multimedia subsystem and I wrote a short program to play MP3 audio files from the command-line ( cmdmp3.exe ). I created a second program that was a GUI application ( cmdmp3win.exe ) for those who didn’t want the console window to show.
Unfortunately, something about the old Microsoft C compiler that I use seems to trigger various anti-malware programs.
I adapted the two programs so that they would build under the MinGW GCC compiler this morning.
The sources and executable files for these programs can be found at:
http://www.mailsend-online.com/wp/cmdmp3new.zip
The Github repo for the sources is here:
https://github.com/jimlawless/cmdmp3
// cmdmp3 // A command-line MP3 player for Windows // (console-mode version) // // License: MIT / X11 // Copyright (c) 2009, 2015 by James K. Lawless // jimbo@radiks.net http://jiml.us // See http://www.mailsend-online.com/license2015.php // // To build, use the following MinGW command: // gcc -o cmdmp3.exe -lwinmm cmdmp3.c #include <windows.h> #include <stdio.h> #include <string.h> void sendCommand(char *); int main(int argc,char **argv) { char shortBuffer[MAX_PATH]; char cmdBuff[MAX_PATH + 64]; printf("cmdmp3 v2.0\n"); printf("Command-line MP3 player\n"); printf("by Jim Lawless - http://jiml.us\n\n"); if(argc<2) { fprintf(stderr,"Syntax:\n\tcmdmp3 \"c:\\path to file\\file.mp3\"\n"); return 1; } // Get the shortened path because the MCI string interpreter uses spaces // as a separator. If spaces appear in the commands, parts of the filename // would be interpreted as paramters to the given command. GetShortPathName(argv[1],shortBuffer,sizeof(shortBuffer)); if(!*shortBuffer) { fprintf(stderr,"Cannot shorten filename \"%s\"\n",argv[1]); return 1; } sendCommand("Close All"); sprintf(cmdBuff,"Open %s Type MPEGVideo Alias theMP3",shortBuffer); sendCommand(cmdBuff); sendCommand("Play theMP3 Wait"); return 0; } // Send a string to the Media Control Interface // If an error occurs, display it and the string // that produced the error. void sendCommand(char *s) { int i; i=mciSendString(s,NULL,0,0); if(i) { fprintf(stderr,"Error %d when sending %s\n",i,s); } }The command line to compile each is as follows:
gcc cmdmp3.c -lwinmm -o cmdmp3.exe gcc cmdmp3win.c -lwinmm -mwindows -o cmdmp3win.exeTo play an MP3 file with either, enter:
cmdmp3 mp3filenameor
cmdmp3win mp3filename
Thanks for writing this program. I just started using etmTk, which is a task manager program on Sourceforge, but it doesn’t have built-in functionality to actually play sound files for reminder alerts. Your program did the trick.
Glad to hear it, Myron. I’ll have to check out etmTk.
I renamed the executable to play.exe and now I tell my friends that my windows cmd is smarter than theirs as it plays files on typing “play filename.mp3”. Thanks a lot.
Thank you Jim, i was made it an installer in batch, but The only thing missing was the background music.Now my batch installer is complete.
thanks again.
Hey Jim, thanks for writing this tool. I’ve just found that it fails to play mp3 files that have spaces in the filenames every time. I tried some ways like and , just doesn’t work. It shows me this:
Error 259 when sending Open Walk Away.mp3 Type MPEGVideo Alias theMP3
Error 263 when sending Play theMP3 Wait
Do you know how to solve this?
I tried some ways like
cmdmp3 “Walk Away.mp3”
and
cmdmp3 “” “Walk Away.mp3”
Doe, could you please try the release at http://www.mailsend-online.com/wp/cmdmp3alt.zip and let me know if this fixes your issue? ( Sorry that this has taken so long! )
New problem 😉
ccM5i9HO.o:cmdmp3win.c:(.text+0x13f): undefined reference to `mciSendStringA@16′
collect2.exe: error: ld returned 1 exit status
What command line are you using to compile?
Is it possible that you’re on a volume that does not allow shortened names?
In the same folder, what output do you see if you type:
dir /x “walk away.mp3”
?
I had used a method in the original code to try to use the shortened version of the filename. Another user said they had luck with using single quotes around the filename. I would have to embed this in a new version ( likely as an option after the filename. )
Thanks for your response!
The output is like this:(Excuse me for using a Chinese system, but I think you can understand what the text means)
———————————————–
E:\m\ali>dir /x “walk away.mp3”
驱动器 E 中的卷是 新加卷
卷的序列号是 7AF3-FC38
E:\m\ali 的目录
2013/09/24 17:03 4,160,288 Walk Away.mp3
1 个文件 4,160,288 字节
0 个目录 36,405,497,856 可用字节
————————————————-
I tried single quotes, but the problem remains. It seems like when I use quotes, cmdmp3 is able to recognize which file to play, yet playing is still unable.
As I suspected, you’re on a volume that doesn’t allow shortened filenames. I’ll have to add an option to enclose the filename in quotes before passing it into the media interface.
Thanks!
It’ll be a while before I am able to do this. Could you please try the following?
Consider the filename walk away.mp3
When you run cmdmp3, please first enclose walk away.mp3 in single-quotes:
‘walk away.mp3’
Then, enclose that entire phrase in double-quotes:
” ‘walk away.mp3’ ”
So that your command reads:
cmdmp3 ” ‘walk away.mp3’ ”
(Please do not copy and paste out of this reply as I think the editor will alter some of the dquote characters. )
After I tried this, the output is
Cannot shorten filename ” ‘walk away.mp3’ “
OK. I’ll try to make a fix, soon.
I’m running Windows 7 and I get the following errors:
cmdmp3 c:\dogs.mp3
Error 277 when sending Open C:\dogs.mp3 Type MPEGVideo Alias theMP3
Error 263 when sending Play theMP3 Wait
Any idea what might be going on?
I had never heard of this until you asked. This thread on another blog revealed the answer; Win7 manages it’s own audio compress/decompress drivers. Scroll down to the bottom post for the solution.
http://www.vbforums.com/showthread.php?764359-RESOLVED-API-mciSendString-type-MPEGVideo-won-t-play-mp3-on-Windows-7
Thanks for responding Jim. I downloaded Win7DSFilterTweaker_6.3.exe and K-Lite_Codec_Pack_1375_Standard and have been experimenting with them. I haven’t found a combination that works yet but I’m going to keep trying.
I tried to compile both programs from source by using MinGW. Cmdmp3 and cmdmp3win were successfully compiled. Cmdmp3 works fine, but cmdmp3win isn´t working at all 😦 No matter what mp3 i try to play,a message box explaining the syntax pops up – no playback at all.
The precompiled cmdmp3win from above works fine…
Any ideas?
What version of Windows are you running?
I’m not sure what could be causing the problem if the console version works correctly. I might need to put together a debugging version to send to you.
What version of MinGW are you using, Mark?
Latest MinGW (2013072300) / Win 7 Pro x64
Mark, I upgraded to the version you specified and I found an error in compiling cmdmp3win.c ( I have a declaration that collides with one in one of the headers I seem to be picking up, now, around the __argc/__argv variables. ) I have commented those references out in a release where I’ve also removed the filename shortening code. Could you please try this release http://www.mailsend-online.com/wp/cmdmp3alt.zip and let me know if it fixes your issues?
I am really sorry!
Used the wrong command line…
Everything is compiling/working fine now 🙂
Glad to hear it!
Yea this isnt working on my windows 10 pro…
Error 277 when sending Open C:\dogs.mp3 Type MPEGVideo Alias theMP3
Error 263 when sending Play theMP3 Wait
See above response to Dave H.
Hi, I appreciated you easy MP3 Reader, but if possible, could you add 2 new options:
1. A possibility to add an argument option to stop playing at end of the file (cmdmp3.exe /stop myfile.mp3).
2. Just add an argument for /? or /help to known how typing command 😉
#1 – Your MP3 play should stop after one playback. Are yours playing continuously with a single invocation of cmdmp3?
Could you add a command to the application to select the Windows Playback device?
Many Thanks
Christoph 🙂
Hi, Christoph. Sorry, but I have no plans to do so at this time. Have you tried other programs/scripts to change the default playback device before calling cmdmp3?
Hi Jim, Thank You for all your efforts! Any way to adjust the volume? My application uses cmdmp3 and winamp together, the only way I can come even close to balancing the output volumes, is to crank winamp full blast but of course then winamp distorts.
Thanks,
John
I have no plans to add sound controls to cmdmp3, but there are some other command-line apps that allow you to control the volume. Those could be used in conjunction with cmdmp3. There’s one called SndVol.exe in %windows%\system32 that has a command-line interface, but the documentation I could find seems sparse. There are some other free ones out there that may be easier to use.
Hi Jim
When trying to compile cmdmp3.c, I get the following error :
D:\Dvpt\SandBox\cmdmp3>gcc -o cmdmp3.exe -lwinmm cmdmp3.c
C:\Users\Laurent\AppData\Local\Temp\cciI2uDK.o:cmdmp3.c:(.text+0x14c): undefined
reference to `mciSendStringA@16′
collect2.exe: error: ld returned 1 exit status
Here is the gcc version, if it matters :
D:\Dvpt\SandBox\cmdmp3>gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-6.3.0/configure –build=x86_64-pc-linux-gnu –host=m
ingw32 –target=mingw32 –with-gmp=/mingw –with-mpfr –with-mpc=/mingw –with-i
sl=/mingw –prefix=/mingw –disable-win32-registry –with-arch=i586 –with-tune=
generic –enable-languages=c,c++,objc,obj-c++,fortran,ada –with-pkgversion=’Min
GW.org GCC-6.3.0-1′ –enable-static –enable-shared –enable-threads –with-dwar
f2 –disable-sjlj-exceptions –enable-version-specific-runtime-libs –with-libic
onv-prefix=/mingw –with-libintl-prefix=/mingw –enable-libstdcxx-debug –enable
-libgomp –disable-libvtv –enable-nls
Thread model: win32
gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)
BTW, libwinmm.a is in the /lib directory :
C:\MinGW\lib>ls libwinmm*.*
libwinmm.a
and
D:\Dvpt\SandBox\cmdmp3>ld –verbose | grep SEARCH_DIR | tr -s ‘; ‘ \r\n
SEARCH_DIR(“/mingw/mingw32/lib”)
SEARCH_DIR(“/mingw/lib”)
SEARCH_DIR(“/usr/local/lib”)
SEARCH_DIR(“/lib”)
SEARCH_DIR(“/usr/lib”)
So where the catch ? 😉
Thanks for your help !
Could you try to compile again adding the -v to the gcc command line…
gcc -v -o cmdmp3.exe -lwinmm cmdmp3.c
…and send me the output?
Hi Jim. Here it is :
D:\Dvpt\SandBox\cmdmp3>gcc -v -o cmdmp3.exe -lwinmm cmdmp3.c
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-6.3.0/configure –build=x86_64-pc-linux-gnu –host=m
ingw32 –target=mingw32 –with-gmp=/mingw –with-mpfr –with-mpc=/mingw –with-i
sl=/mingw –prefix=/mingw –disable-win32-registry –with-arch=i586 –with-tune=
generic –enable-languages=c,c++,objc,obj-c++,fortran,ada –with-pkgversion=’Min
GW.org GCC-6.3.0-1′ –enable-static –enable-shared –enable-threads –with-dwar
f2 –disable-sjlj-exceptions –enable-version-specific-runtime-libs –with-libic
onv-prefix=/mingw –with-libintl-prefix=/mingw –enable-libstdcxx-debug –enable
-libgomp –disable-libvtv –enable-nls
Thread model: win32
gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)
COLLECT_GCC_OPTIONS=’-v’ ‘-o’ ‘cmdmp3.exe’ ‘-mtune=generic’ ‘-march=i586′
c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/cc1.exe -quiet -v -iprefix c:\mingw\b
in\../lib/gcc/mingw32/6.3.0/ cmdmp3.c -quiet -dumpbase cmdmp3.c -mtune=generic –
march=i586 -auxbase cmdmp3 -version -o C:\Users\Laurent\AppData\Local\Temp\ccLjP
gsI.s
GNU C11 (MinGW.org GCC-6.3.0-1) version 6.3.0 (mingw32)
compiled by GNU C version 6.3.0, GMP version 6.1.2, MPFR version 3.1.5,
MPC version 1.0.3, isl version 0.15
GGC heuristics: –param ggc-min-expand=100 –param ggc-min-heapsize=131072
ignoring duplicate directory “c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/inclu
de”
ignoring nonexistent directory “/mingw/include”
ignoring duplicate directory “c:/mingw/lib/gcc/../../include”
ignoring duplicate directory “c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/inclu
de-fixed”
ignoring duplicate directory “c:/mingw/lib/gcc/../../lib/gcc/mingw32/6.3.0/../..
/../../mingw32/include”
ignoring nonexistent directory “/mingw/include”
#include “…” search starts here:
#include search starts here:
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/include
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/../../../../include
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/include-fixed
c:\mingw\bin\../lib/gcc/mingw32/6.3.0/../../../../mingw32/include
End of search list.
GNU C11 (MinGW.org GCC-6.3.0-1) version 6.3.0 (mingw32)
compiled by GNU C version 6.3.0, GMP version 6.1.2, MPFR version 3.1.5,
MPC version 1.0.3, isl version 0.15
GGC heuristics: –param ggc-min-expand=100 –param ggc-min-heapsize=131072
Compiler executable checksum: 384cad586f05ed581a9c068b2f18b408
COLLECT_GCC_OPTIONS=’-v’ ‘-o’ ‘cmdmp3.exe’ ‘-mtune=generic’ ‘-march=i586′
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/as.exe -v -o C:\U
sers\Laurent\AppData\Local\Temp\ccxinGsd.o C:\Users\Laurent\AppData\Local\Temp\c
cLjPgsI.s
GNU assembler version 2.28 (mingw32) using BFD version (GNU Binutils) 2.28
COMPILER_PATH=c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/;c:/mingw/bin/../libexec
/gcc/;c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/
LIBRARY_PATH=c:/mingw/bin/../lib/gcc/mingw32/6.3.0/;c:/mingw/bin/../lib/gcc/;c:/
mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/lib/;c:/mingw/bin/../lib/
gcc/mingw32/6.3.0/../../../
COLLECT_GCC_OPTIONS=’-v’ ‘-o’ ‘cmdmp3.exe’ ‘-mtune=generic’ ‘-march=i586′
c:/mingw/bin/../libexec/gcc/mingw32/6.3.0/collect2.exe -plugin c:/mingw/bin/../
libexec/gcc/mingw32/6.3.0/liblto_plugin-0.dll -plugin-opt=c:/mingw/bin/../libexe
c/gcc/mingw32/6.3.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\Laurent\Ap
pData\Local\Temp\ccB4Fr17.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-p
ass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-
lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt
-plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugi
n-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-p
ass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=
-lgcc_eh -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwe
x -plugin-opt=-pass-through=-lmsvcrt -Bdynamic -o cmdmp3.exe c:/mingw/bin/../lib
/gcc/mingw32/6.3.0/../../../crt2.o c:/mingw/bin/../lib/gcc/mingw32/6.3.0/crtbegi
n.o -Lc:/mingw/bin/../lib/gcc/mingw32/6.3.0 -Lc:/mingw/bin/../lib/gcc -Lc:/mingw
/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/lib -Lc:/mingw/bin/../lib/gcc/
mingw32/6.3.0/../../.. -lwinmm C:\Users\Laurent\AppData\Local\Temp\ccxinGsd.o -l
mingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser
32 -lkernel32 -lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt c:/mingw/bi
n/../lib/gcc/mingw32/6.3.0/crtend.o
C:\Users\Laurent\AppData\Local\Temp\ccxinGsd.o:cmdmp3.c:(.text+0x14c): undefined
reference to `mciSendStringA@16’
collect2.exe: error: ld returned 1 exit status
Thanks !
I tried the command-line options (which used to work ages ago) and I received a slightly different error message. However, when I moved the command-line parameters around, things went a little better:
Please try:
gcc cmdmp3.c -lwinmm -o cmdmp3.exe
gcc cmdmp3win.c -lwinmm -mwindows -o cmdmp3win.exe
Note that this player hasn’t worked for a while on Windows 10. The OS doesn’t go through the multimedia libs to play MP3’s unless you install some codecs to make that happen.
Hi Jim – Excellent ! Thanks !
For the record, I had to use _argv and _argc (not doubled underscore), and add to cmdmp3win.c to make it work.
Anyway, thanks for your help.
I have no idea when those parameters became positional … the old format used to work. Yes, I had someone tell me about _argc and _argv a while back, too. I just don’t compile this code any more, so I don’t catch any of these as they break.
Thanks, Jim,
such a simple tool, yet strangely hard to find amid the plelthora of monster applications (wmplayer, winamp, groove, itunes &c)
Wanted to make the windowless version my default player – but forseeing a problem stopping if I accidentally started the wrong piece, I made the windowed version my default, and adjusted its window to a very small size, just big enough to click and [Ctrl]C as and when required.
Best tools, do one job, and do it well.
David
Glad to hear it, David. I thought that cmdmp3’s days were numbered when it stopped working on my newer PC, but it continues to work on my other Windows machines running the same version of the OS.
Jim,
Thanks so much for this valuable little utility.
I downloaded it, extracted the executable I wanted and copied it to C:\Windows\System32
Now I can pretend when using git bash on windohs that I really am running a decent machine, although I might have changed the filename to “aplay.exe” just to be consistent over four or five machines.
aplay angry.wav
Brilliant!
If it’s playing WAV files then it’s not my utility. 😉 I do plan on making a WAV file player equivalent at some point, though.
I hate to be that guy… but your utility is playing wav files on my windows box unless some crazy aliasing is working with WSL.
It plays wav files… Should I create an issue on your github? 😛
https://photos.app.goo.gl/jnoKoDgiMhjhtMZSA
Wow! Sometimes I even amaze myself!
I’ll have to try this on one of my alternate machines. cmdmp3 won’t run on my primary Windows machine. I have issues on it similar to the ones others describe above.
You’re right, Ron. It worked. I guess I’ll add the appropriate WAV API call into the source as an option as well as MessageBeep() in the near future. I want to add the appropriate WAV API call so that WAV’s can be played no matter what media drivers have been installed.