Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
This is a walkthrough on how to install the MOC command-line music player on OS X. The procedure was tested in Mountain Lion.


I waited for years for a Homebrew formula for MOC. I finally found one today, but it didn't work for me. So I decided to try to compile it from source.


Here is a list of requirements, taken directly from the MOC README:

  • UNIX system with POSIX threads (e.g., Linux or FreeBSD)
  • ncurses (probably already installed in your system)
  • C and C++ compilers (MOC is written in C, but libtool and some decoder plugins require a C++ compiler)
  • libdb version 4 or later (unless configured with --disable-cache)

To support audio formats you need:

For network streams:

For resampling (playing files with sample rate not supported by your hardware):

For JACK (low-latency audio server):

For librcc (fixes encoding in broken mp3 tags):

So first you need to install Xcode and Homebrew if you don't already have them installed; I'll let you Google on how to do that. You also need to install a dependency that is not listed above: BerkeleyDB. Luckily there is a Homebrew package for it:

% brew install berkeley-db

Edit: The BerkeleyDB dependency is actually listed above, as libdb. Thanks to John Fitzgerald, MOC's Maintainer, for the note.

NOTE: % is my prompt, don't copy it, copy just the brew command!

Then you need to install JACK, because it's the audio server that will be used by MOC:

% brew install jack

Finally you need to install the required library to play MP3s, and other audio formats. All my music is in MP3 so I just had to install two libraries:

% brew install libmad
% brew install libid3tag

Compiling MOC from source

First you need to download MOC from here. I downloaded the Development release (2.5.0-beta1). Next you need to go extract the archive you just downloaded:

% cd ~/Downloads
% tar xvjf moc-2.5.0-beta1.tar.bz2
% cd moc-2.5.0-beta1

Next you need to configure, compile and install MOC:

% ./configure --prefix=/usr/local/Cellar/moc/2.5.0-beta1 --with-jack --enable-debug --without-ffmpeg
% make
% make install

NOTE: I haven't compiled MOC with the --without-ffmpeg option myself, but it should work. If it doesn't, uninstall ffmpeg using brew uninstall ffmpeg. A big Thank you to jcf for the tip!

Configuring MOC

Now that you installed MOC, you need to configure it. The first thing I needed to do, is add the bin directory to my $PATH:

  • If you are using ZSH, add this line to your .zshrc:
path=( /usr/local/Cellar/moc/2.5.0-beta1/bin $path )
  • If you're using Bash, add this line to your .bashrc:

Next, you need to create a directory for MOC, in your home directory:

% mkdir ~/.moc

Let's skip the config file step for a minute and let's create a custom theme. First, create the themes directory:

% mkdir ~/.moc/themes

I use a theme I found on the CrunchBang forums. All you need to do is to create a new file for the theme with the following content:

% vim ~/.moc/themes/rhowaldt_theme
background           = default    default
frame                = default    default
window_title         = default    default
directory            = blue       default
selected_directory   = blue       default    reverse
playlist             = default    default
selected_playlist    = default    default    reverse
file                 = default    default
selected_file        = default    default    reverse
marked_file          = blue       default    bold
marked_selected_file = blue       default    reverse
info                 = default    default
selected_info        = default    default
marked_info          = blue       default    bold
marked_selected_info = blue       default    bold
status               = default    default
title                = blue       default    bold
state                = default    default
current_time         = default    default
time_left            = default    default
total_time           = default    default
time_total_frames    = default    default
sound_parameters     = default    default
legend               = default    default
disabled             = default    default
enabled              = blue       default    bold
empty_mixer_bar      = default    default
filled_mixer_bar     = default    default    reverse
empty_time_bar       = default    default
filled_time_bar      = default    default    reverse
entry                = default    default
entry_title          = default    default
error                = default    default    bold
message              = default    default    bold
plist_time           = default    default

NOTE: I removed the documentation comments from the theme, but you can find the whole theme file here

Now you need a config file. Let's copy the example config file that came with MOC:

% cp /usr/local/Cellar/moc/2.5.0-beta1/share/doc/moc/config.example ~/.moc/config

Next, edit it with the following config:

% vim ~/.moc/config

NOTE: This configuration assumes that you are using iTerm2. Feel free to fiddle with it.

ReadTags = yes
MusicDir = /Users/aziz/Music
StartInMusicDir = yes
SoundDriver = JACK
XTerms = xterm-256color
Theme = rhowaldt_theme
MOCDir = ~/.moc
UseRCC = no're done configuring MOC!

Running MOC

Before you run MOC, you need to run JACK, otherwise it won't work! You can run it manually using this command:

% jackd -d coreaudio

But that's tedious to do! So let's create a launch agent:

% vim ~/Library/LaunchAgents/org.jackaudio.jackd.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

And load that launch agent:

% launchctl load ~/Library/LaunchAgents/org.jackaudio.jackd.plist

Now you are finally ready to use MOC!!!

% mocp

To see the list of available commands, type ? once in MOC. The cool thing about this is that you can run MOC in the background: just type q (lowercase not upercast).

One more thing

I found a Gist that I created a while ago. It's a bash script to enable Growl notifications for MOC! I doubt I wrote it myself, but I can't find its origins so I can't really give credit where credit is due; if you wrote this little script, post a comment and I'll update the Gist. Here it is:


while out=$(/usr/local/Cellar/moc/2.5.0-beta1/bin/mocp -i); do

  # Parse mocp output.
  while IFS=: read -r field value; do
    case $field in
      Artist) artist=$value;;
      Album) album=$value;;
      SongTitle) title=$value;;
  done <<< "$out"

  # Don't do anything if we're still on the same song.
  [[ "$artist-$album-$title" = "$current" ]] && { sleep 1; continue; }

  # Growl notify this information
  if [[ $album && $artist && $title ]]; then
    /usr/local/bin/growlnotify -t "moc: $title" -n "mocp" -m "by $artist"$'\n'"(album: $album)"

  # Remember the current song.


Put that anywhere you want, it really doesn't matter. I've put it the bin directory in my Home directory. Make sure you make the script executable with chmod a+x Again, you can run the script manually, but it's tedious, so I created a launch agent:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

And don't forget to load the launch agent:

% launchctl load ~/Library/LaunchAgents/me.azizlight.mocgrowl.plist

The cherry on the cake

Yes there is YET ONE MORE THING! I managed to map the function keys F7, F8 and F9 to moc actions using applescript! Here is how to do it:

  • Open Automator
  • Create a new Service
  • Choose "Run AppleScript" from the list of actions
  • Insert the script below in the mini AppleScript editor
  • Save
  • Go in the Keyboard Shortcuts System Preferences
  • Locate your new service
  • Assign it a shortcut

I chose those function keys because they match the media keys. Do this for every script show below (three times in total):

-- This is the script to Play/Pause
do shell script "/usr/local/Cellar/moc/2.5.0-beta1/bin/mocp -G"
-- This is the script to go to the Next Song
do shell script "/usr/local/Cellar/moc/2.5.0-beta1/bin/mocp -f"
-- This is the script to go to the Previous Song
do shell script "/usr/local/Cellar/moc/2.5.0-beta1/bin/mocp -r"

Alfred Workflow

I also created an Alfred Workflow to show the current playing song and triggering the play/pause/next/previous functionality. The Workflow can be downloaded here. Once downloaded, just double-click on the file and it should install it.

Voila! A full headless command-line alternative to iTunes!


I created a Homebrew formula, it's a pull request right now, but it works. (I finished it before I saw this)
I'll reference this gist in the caveats as it seems really useful.

Very awesome. Thank you for this gist!! Baller.

@azizLIGHT: have you had any difficulty with MP3 playback? Which version of ffmpeg are you using?

dpsk commented Oct 7, 2013

Great stuff, maybe it makes more sense to use apple notifications, instead of Growl?
I added notes about this in my fork

Super *
Worked for me with both moc 2.5.0-beta1 / beta2

The link to the theme's original is 404ed, do you still have the documented version to put online?

Second plist will not work. Just because the script will terminate all the time. Your script needs mocp to be already running.

We can extend your script. And use Open Source terminal-notifier instead of proprietary Growl.


while :; do

    out=$(mocp -i)

    if [[ $out ]]; then

        # Parse mocp output
        while IFS=: read -r field value; do
            case $field in
                Artist) artist=$value;;
                Album) album=$value;;
                SongTitle) title=$value;;
        done <<< "$out"

        # Ignore if we are still on the same song
        [[ "$artist-$album-$title" = "$current" ]] && { sleep 1; continue; }

        # Show notification using terminal-notifier
        if [[ $album && $artist && $title ]]; then
            terminal-notifier -title "$title" -subtitle "$artist" -message "$album"

        # Store current song

        sleep 1


First of all, thanks for the how-to, I keep coming here everytime I re-install mocp!

Alfred workflow is 403 on your dropbox link, can you upload? I'm using spark with exactly the same commands you used on your applescript via automator, does the trick too. But got curious of the alfred workflow!

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