Overview
Here are the steps that worked for me:
- Disable System Integrity Protection (see below for details).
- Put your custom ringtone file in /System/Library/PrivateFrameworks/ToneLibrary.framework/Versions/A/Resources/Ringtones/
- Edit the system's property list of ringtones at /System/Library/PrivateFrameworks/ToneKit.framework/Versions/A/Resources/TKRingtones.plist (see below for details).
- Choose your custom ringtone in FaceTime preferences.
- Re-enable System Integrity Protection (see below for details).
Enabling/Disabling System Integrity Protection
It looks like in macOS Sierra (actually starting from El Capitan), Apple has implemented a System Integrity Protection technology that restricts access to /System. In order to play around with custom ringtones, you would need to disable System Integrity Protection
To enable or disable System Integrity Protection [...]
- Boot to Recovery OS by restarting your machine and holding down the
Command and R keys at startup.
- Launch Terminal from the Utilities
menu.
- Enter the following command:
$ csrutil enable
[or use the command $ csrutil disable
to disable System Integrity Protection]
After enabling or disabling System Integrity Protection on a machine,
a reboot is required.
Sources: Apple Support, Apple Developer
Editing TKRingtones.plist
In order to make your custom ringtone show up in the list of ringtones in FaceTime preferences, you will need to edit the file /System/Library/PrivateFrameworks/ToneKit.framework/Versions/A/Resources/TKRingtones.plist using TextEdit (or some other text editor -- you can also use Xcode's developer tools for a nicer interface). Specifically, add <string>system:Custom Ringtone Name</string>
at the location shown below (you should replace "Custom Ringtone Name" with the name of your ringtone file).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
// lots of stuff omitted here
<key>modern</key>
<array>
<string><default></string>
<string>system:Custom Ringtone Name</string>
<string>system:Apex</string>
<string>system:Beacon</string>
<string>system:Bulletin</string>
// lots of stuff omitted here
</array>
<key>sort</key>
<true/>
</dict>
</plist>