4

I want to make an application, say VLC, the default player for all the file types it supports, without going through all of them individually.

I might not even know what all the supported formats are (as VLC can read 100s of formats) and still want to set it as the default player for all of them.

I was able to do this using the terminal, with the procedure posted below.

Is there an easier way to do it that doesn't require the user to be a developer?

nohillside
  • 100,768
Tobia
  • 209

4 Answers4

4

While RCDefaultApp is a bit old, it still works

This gives you a decent GUI interface to control default apps

demure
  • 1,351
  • This is nice, but it would still makes me go through 100+ clicks to set VLC as the default player for all media files. – Tobia May 25 '13 at 18:06
  • 1
    No it doesn't? System Pref -> RCDefaultApp -> Apps -> VLC. Then click on the check box for the whole 'Extension' section and click 'set as default'. – demure May 25 '13 at 18:12
1

As mentioned above one method is to use duti, here's a script which you could put in a crontab so when an external app changes your extensions, your script will change them back again;

1.Install duti with HomeBrew:

brew install duti

2.find all your apps bundle id's with:

mdls -name kMDItemCFBundleIdentifier -r /Applications/VLC.app

for example in this case will output: org.videolan.vlc

3.change the default app:

duti -s org.videolan.vlc .mp4 all
#!/bin/bash

#========================================================================
#  FILE:  set_default_apps.sh
#  DESCRIPTION:  Changes default apps for extensions
#  AUTHOR:  Scott Granneman (RSG), scott@chainsawonatireswing.com
#  COMPANY:  Chainsaw on a Tire Swing (http://ChainsawOnATireSwing.com)
#  VERSION:  0.1
#  CREATED:  09/17/2012 21:44:01 CDT
#  REVISION:   
#========================================================================

{ cat <<eof
com.macrabbit.Espresso:css
com.valloric.Sigil.app:epub
cx.c3.theunarchiver:gz
com.sublimetext.2:markdown
com.sublimetext.2:md
com.sublimetext.2:mdwn
com.sublimetext.2:mediawiki
cx.c3.theunarchiver:rar
com.sublimetext.2:sh
cx.c3.theunarchiver:tar
com.sublimetext.2:text
com.sublimetext.2:txt
com.sublimetext.2:xml
cx.c3.theunarchiver:zip
eof
} | grep . |
while IFS=$':' read bundle_id extension ; do
  # Grep to see if Bundle ID exists, sending stdout to /dev/null
  /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump | grep $bundle_id > /dev/null  
  # Save exit status (0=success & 1=failure)
  status=$?
  # If exit status failed, notify me & exit; if not, change default app for extension
  if test $status -eq 1 ; then
    echo "$bundle_id doesn't exist! Fix the script!"
    #exit
  else
    echo -e "\nChanging $extension so it opens with $bundle_id …\n"
    duti -s $bundle_id .$extension all
    echo -e "Here's proof…\n"
    duti -x $extension
    echo -e "\n----------"
  fi
done
  • you can find all your apps extensions with this voodoo from @Lri posted above, and then use/paste the result in the script above:
app="VLC.app" ; \
bundleid=`mdls -name kMDItemCFBundleIdentifier -r /Applications/$app` ; \
dump=$(/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump); \
plutil -convert xml1 /Applications/$app/Contents/Info.plist -o - |  \
sed -n '/LSItemContentTypes/,/\/array/p' |  \
sed -En 's|.*string>(.*)</string.*|\1|p' |  \
while read u; do  \
awk "/uti: *$u/,/tags:/"  \
<<< "$dump"; done |  \
sed -En 's/[[:space:]]*tags: *(.+)/\1/p' |  \
sed $'s/, /\\\n/g' |  \
grep '^\.' | sort -u |  \
awk '{print "'$bundleid':" substr($1,2,length($1)) }'
  • then put the script in a crontab that runs every x minutes/hours
Motsel
  • 959
1
  1. Find the application's Info.plist file and convert it to xml format if needed.
    VLC's plist file is already in xml format, otherwise you'd have to do:
    plutil -convert xml1 /Applications/VLC.app/Contents/Info.plist
  2. Perform the necessary dark magic to extract the list of supported file extensions, with your preferred wand (here is awk, but sed, perl, and others would work just as well):
    awk '/CFBundleTypeExtensions/{t=1} /<\/array>/{t=0} t&&/<string>/{gsub(/\t*<\/?string>/,"");print}' /Applications/VLC.app/Contents/Info.plist
  3. Check the output to make sure you really got the list of extensions and that you really want to associate all those types with the app.
  4. Recall the last command and edit it in order to create an empty file in your current directory for every file extension in the list:
    for i in $( ≪awk command as before≫ ); do touch dummy.$i; done
  5. Open your home folder in the Finder, select all the "dummy" files and open a collective inspector for all of them: option+command+i
  6. Set the application in Open With and use the Change All button.
  7. Trash the dummy files.
Tobia
  • 209
1

I wouldn't want to associate VLC with all types it supports (like mp3, iso, or utf), but I have added this to a duti configuration file:

org.videolan.vlc .avi all
org.videolan.vlc .flac all
org.videolan.vlc .flv all
org.videolan.vlc .mkv all
org.videolan.vlc .mov all
org.videolan.vlc .mp4 all
org.videolan.vlc .mpg all
org.videolan.vlc .wmv all

duti converts extensions that are listed in UTI declarations to UTIs automatically, so you can specify the types like .jpg instead of public.jpeg. See com.apple.LaunchServices.plist. The UTIs of some extensions like .mkv depend on what applications were installed first.

Many applications only list UTIs (LSItemContentTypes) and not extensions (CFBundleTypeExtensions) in the Info.plist. This would list the UTIs and print extensions associated with them:

dump=$(/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump); plutil -convert xml1 /Applications/TextEdit.app/Contents/Info.plist -o - | sed -n '/LSItemContentTypes/,/\/array/p' | sed -En 's|.*string>(.*)</string.*|\1|p' | while read u; do awk "/uti: *$u/,/tags:/" <<< "$dump"; done | sed -En 's/[[:space:]]*tags: *(.+)/\1/p' | sed $'s/, /\\\n/g' | grep '^\.' | sort -u

Lri
  • 105,117