How to Pass Real Time Data to BTT Plugin

Hey guys,

I am currently working on the BTT plugin for my audio Visualizer for the Touch Bar. However, it seems that there are certain roadblocks in getting this working inside BTT.

Does anybody know how to pass real time data to a custom BTT plugin? It seems that some stuff can be transferred, but not real time data. Passing the data would allow for the visuals to be recreated by the custom plugin.

The other option would be to write the entire audio Visualizer inside the plugin, but it seems you cannot ask for audio read permission from a plugin inside BTT. Is there any way to get permission? If BTT asked for permission would it be able to transfer to a plugin? @Andreas_Hegenberg

asking for the permissions should work. I’ll have a look!

Do you maybe have some sinple sample code I could test?

Hey Andreas,

Thanks for taking a look - I have some code where it is trying to get the permission here:

BetterTouchToolPlugins-master copy.zip (207.6 KB)

Work was done inside the CustomViewVC.swift file inside BTTTouchBarPluginSampleCustomView. Also, this code is using AMCoreAudio framework Swift Package.

There is a setup() function called when the plugin view loads, you can check messages logged in Console.app, if the permission worked, then you should see audio data printed in Console.app, otherwise the data will be empty. Just make sure there is some audio playing when testing. It does use soundflower to get the system audio so you will need to have that installed.

Alternatively, you can uncomment the lines shown below within the setup() function and that will tell you whether permission was granted to the plugin or not.

switch AVCaptureDevice.authorizationStatus(for: .audio) {
case .authorized: // The user has previously granted access to the camera.
print("ok")
os_log("---------- OK ++++++++ ", log: OSLog.viewCycle, type: .debug)

case .notDetermined: // The user has not yet been asked for camera access.
AVCaptureDevice.requestAccess(for: .audio) { granted in
if granted {
print("granted")
os_log("++++++++== ---------- granted ++++++++ ", log: OSLog.viewCycle, type: .debug)
}
}
os_log("---------- not determined ++++++++ ", log: OSLog.viewCycle, type: .debug)

case .denied: // The user has previously denied access.
os_log("---------- denied ++++++++ ", log: OSLog.viewCycle, type: .debug)
return

case .restricted: // The user can't grant access due to restrictions.
os_log("---------- restricted ++++++++ ", log: OSLog.viewCycle, type: .debug)
return
}

If the plugin has the permission, should see this logged in Console.app:
"---------- OK ++++++++ "

Thanks Andreas!

Hey @Andreas_Hegenberg , just wanted to check in and see if you had a chance to look at the audio permissions.

Thanks!

@jake.fishtech when I try to load the plugin in BTT I get the following error:

[access] This app has crashed because it has a hardened runtime and attempted to access privacy-sensitive data without an entitlement indicating its intent to access this data.  
The app must have the 'com.apple.security.device.audio-input' entitlement.

Do you think that's the issue? Or didn't it even work in the sample project for you? (There I seem to get the permissions without problems in my quick test)

I can add that entitlement to BTT. Are there any others that are necessary?

@Andreas_Hegenberg I think that is the issue - that the entitlements need to be added to BTT for the plugin to make use of them. We need the entitlement 'com.apple.security.device.audio-input' as well as 'com.apple.security.device.microphone'.

I could get the permissions to pop up in the Xcode project, but it seems that I was having trouble accessing the audio data from inside that Xcode project and inside BTT once the plugin was installed. I think if we can add those two entitlements it should (fingers crossed) allow us to access the audio data from the plugin.