This is a plugin that allows the Elgato Stream Deck to control your camera and microphone in a Google Meet call. It provides toggle buttons that show whether your camera and mic are on or off, and they update whenever you press a Stream Deck button or mute/unmute directly in Meet. It also provides some other buttons to control various elements of the Meet web UI.
This plugin works in conjuction with our Google Chrome / Mozilla Firefox browser extension, which is required for this plugin to function.
Developed and tested primarily on macOS 15.0, Python 3.13.0, Chrome 130, and Stream Deck app v6.6. It should work on Windows or in Firefox as well.
- If you're running on an Apple Silicon Mac (e.g. an M1 chip), you must have Apple's Rosetta 2 installed. If you don't (or if you're not sure), open Terminal and run this command:
softwareupdate --install-rosetta --agree-to-license
-
From the Releases page, download the
com.chrisregado.googlemeet.streamDeckPlugin
package and open it. The Stream Deck desktop software will prompt you to install the plugin. -
The browser extension is not in the web store, so we'll install it manually:
For Google Chrome:
- From the Releases page, download the
chrome-extension
zip file and extract it somewhere you can keep it. (If you move the folder after installing, Chrome will uninstall the extension from your browser and you'll have to reinstall it.) - From Chrome's extension settings page (
chrome://extensions/
), turn on "Developer mode" using the toggle at the top-right corner of the page. - Click the "Load unpacked" button at the top-left corner, and select the folder you extracted the zip to earlier.
- You can turn Developer mode back off now if you want.
For Mozilla Firefox:
- From the Releases page, download the Firefox extension
.xpi
file. - From Firefox's extension settings page (
about:addons
), click the Settings cogwheel at the top-right of the page, click "Install Add-on From File...", and select the.xpi
file that you just downloaded. - Click "Add" on the Firefox popup to allow the extension to install.
- From the Releases page, download the
-
If you use an ad blocker (such as uBlock Origin with the EasyPrivacy filter list), you may have to add meet.google.com as a trusted site in your blocker's settings to allow the browser Extension to work. (Some filters block websockets to 127.0.0.1, which this extension needs to communicate with the Stream Deck.)
-
Add some buttons to your Stream Deck, and start a Google Meet call to try them out!
It's safe to delete the com.chrisregado.googlemeet.streamDeckPlugin
file once it's installed. However, on Windows, you may need to quit the Stream Deck desktop software (by right clicking its icon in the Windows task tray and clicking Quit) and re-launch it to avoid "action can't be completed because the file is open" errors.
To update the Stream Deck plugin, download and open the new plugin package just like when you initially installed it. If you experience any glitches after updating (such as on/off icons not changing on the toggle buttons), please try deleting your Meet buttons and re-adding them to your Stream Deck in the Stream Deck desktop app.
To update the browser extension, uninstall your existing version from your browser's Extension Settings page, and then follow the installation instructions again to install the new version.
In Chrome, go to your extensions settings page (chrome://extensions/
) and click the Remove button for "Stream Deck Google Meet Actions".
In Firefox, go to your extensions settings page (about:addons
), click the 3 dots button next to "Stream Deck Google Meet Actions", and click Remove.
In the Stream Deck desktop app, right click on one of the Google Meet actions in the list on the right-hand side of the window, and click the "Uninstall..." button.
- If Chrome won't let you enable the extension because it was not installed from the web store, you may need to allowlist the extension. On Windows, you can do this by editing the registry. Under both
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionInstallWhitelist
andHKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome\ExtensionInstallAllowlist
add a string value, with the name "1" (or a greater number if "1" already exists). The value should be the extension ID, which you can get from chrome://extensions/ with Developer Mode on. If this does not work or you're on another operating system, you may find this post helpful.
The Stream Deck plugin launches a localhost-only Websocket server on port 2394, which our browser extension connects to. The plugin and browser extension send messages back and forth over that websocket to notify the Stream Deck when Meet changes its device on/off status, and simulates Meet mute button clicks in your browser when you press a key on your Stream Deck.
The Stream Deck plugin code is in the streamdeck-plugin
directory. The browser extension code is in the browser-extension
directory. The com.chrisregado.googlemeet.sdPlugin
directory contains our Stream Deck assets and it becomes our Stream Deck plugin distributable once we bundle our code with the Elgato streamdeck
CLI.
The plugin is written in Python. Create a venv to hold your package's dependencies, and install those dependencies:
MacOS:
cd streamdeck-plugin
python3 -m venv venv/
source venv/bin/activate
pip install -r requirements.txt
Windows:
cd streamdeck-plugin
python3 -m venv venv/
venv\Scripts\activate.bat
pip install -r requirements.txt
Remember that virtualenvs are not portable. If you move this folder at all, you'll have to delete the venv and re-create it.
MacOS:
cd streamdeck-plugin
source venv/bin/activate
python -m unittest
Windows:
cd streamdeck-plugin
venv\Scripts\activate.bat
python -m unittest
We use pyinstaller
to bundle our code, dependencies, and a Python runtime environment into an executable. We put that executable into the com.chrisregado.googlemeet.sdPlugin
folder, which in turn gets zipped up by the Elgato streamdeck CLI tool as our final distributable plugin package. That plugin package ends up including any assets we need (e.g. icons), the manifest.json
file that defines our plugin for the Stream Deck desktop app, and our executable plugin code. Double-click that plugin package and the Stream Deck software will prompt you to install it.
Our plugin code is written in Python, but the Elgato CLI tool is distributed as a Node module, so you'll need Node.js installed.
To build the plugin:
MacOS:
cd streamdeck-plugin
source venv/bin/activate
rm -rf ../com.chrisregado.googlemeet.sdPlugin/dist/macos
pyinstaller --clean --dist "../com.chrisregado.googlemeet.sdPlugin/dist/macos" src/main.py
rm -rf build
Windows:
cd streamdeck-plugin
venv\Scripts\activate.bat
rmdir /q /s "..\com.chrisregado.googlemeet.sdPlugin\dist\windows"
pyinstaller --clean --dist "..\com.chrisregado.googlemeet.sdPlugin\dist\windows" src\main.py
rmdir /q /s build
Note that the resulting executable is only valid for the OS you built it on. MacOS and Windows bundles must be created separately from a machine/VM of that OS, and then combined into the com.chrisregado.googlemeet.sdPlugin/dist/
folder with macos
and windows
subdirectories for release.
If you're just testing locally (so you only care about one OS), you can place any file in the other OS's executable location (CodePath
s from manifest.json
) to appease the Elgato packaging tool. Example:
# If you're running macOS:
mkdir -p com.chrisregado.googlemeet.sdPlugin/dist/windows/main
touch com.chrisregado.googlemeet.sdPlugin/dist/windows/main/main.exe
# If you're running Windows:
mkdir com.chrisregado.googlemeet.sdPlugin\dist\macos\main
type nul > com.chrisregado.googlemeet.sdPlugin\dist\macos\main\main
Or, if you don't ever plan on publishing your local builds, delete the other OS's CodePath and OS
entry in manifest.json so you don't have to worry about multi-OS support.
Finally, use Elgato's streamdeck
CLI tool to bundle everything into the Stream Deck plugin distributable that you can install or send to users. From the root of this git repo, run:
npm install -g @elgato/cli
streamdeck pack --output ./build/ --force com.chrisregado.googlemeet.sdPlugin
In the Stream Deck desktop app, uninstall any old copies of the plugin because the app won't overwrite your installation unless the new build has a newer version number.
You can then double-click the ./build/com.chrisregado.googlemeet.streamDeckPlugin
file to install your build of the plugin into the Stream Deck desktop app.
Our build tools rely on Node.js, so make sure you have Node.js installed.
Follow the usual "Load unpacked" installation instructions described above, but point Chrome at the browser-extension
folder of your git workspace instead of using a release artifact. You can then edit the extension's source code and click the reload button on Chrome's extension settings page. (No build commands/steps are needed.) See https://developer.chrome.com/extensions/getstarted for more details.
This browser extension is primarily built and tested in Google Chrome. Using Chrome will be the smoother experience, but you can use Firefox if you wish.
The Firefox extension requires a build step before it can be loaded. We have a helper script to package up the browser extension and launch a Firefox window that has it installed. Simply run:
cd browser-extension
npm install
npm run dev-firefox
While the session is active, you can run npm run build
again and your changes will be hot-reloaded in your browser.
As an alternative to npm run dev-firefox
, you can manually build and load the extension:
cd browser-extension
npm install
npm run build
npm run package-firefox
This will create a file named browser-extension/build/stream_deck_google_meet_actions-0.0.1.zip
containing the built extension.
Then to install it, in Firefox go to about:debugging
, open the "This Firefox" tab, click "Load Temporary Add-on...", and select the browser-extension/build/stream_deck_google_meet_actions-0.0.1.zip
file.
We use NPM scripts defined in browser-extension/package.json
to help with building and packaging the browser extension.
We have the following commands:
npm run build
: Builds the extension for both Chrome and Firefox. Outputs builds tobrowser-extension/build/chrome
andbrowser-extension/build/firefox
respectively. Runs both locally and in CI jobs. When the commit you're building is tagged with a version number, modifies the version numbers of the extension manifests to match the tag (for building release artifacts in CI).npm run clean
: Deletes any old builds of the extension in your working copy (browser-extension/build/
). Intended for use when running locally.npm run package-chrome
: Zips up your most recent build of the Chrome extension (browser-extension/build/chrome
). Outputs tobrowser-extension/build/chrome-extension.zip
. Intended to be used in CI jobs. If running locally, note that we assume your have thezip
CLI tool (for macOS/Linux) or PowerShell (for Windows) available on your path.npm run package-firefox
: Zips up your most recent build of the Firefox extension (browser-extension/build/firefox
). Outputs tobrowser-extension/build/firefox-extension.zip
. Intended to be used in CI jobs.npm run sign-firefox
: Submits your most recent build of the Firefox extension (browser-extension/build/firefox
) to the Firefox Add-on Hub for review and signing, but does NOT list it in the public add-on store. Usually takes 1-2 minutes, assuming Mozilla auto-approves it. If successful, a signed XPI file will be saved to the build directory (e.g.browser-extension/build/streamdeck_googlemeet-0.0.1.xpi
) that can be used to install the extension in Firefox. This should generally only be run from CI. If testing locally, note that you must set theWEB_EXT_API_KEY
environment variable to be your Add-on Hub API key's "JWT issuer" andWEB_EXT_API_SECRET
to be your "JWT secret".npm run package-all
: Convenience command to runnpm run build
,npm run package-chrome
, andnpm run package-firefox
. Intended for use when running locally.npm run dev-firefox
: Builds the extension and launches a Firefox window that has the extension temporarily installed, to help with testing during development. Intended for use when running locally.npm run lint-firefox
: Performs some of the same basic validations that the Firefox Add-on Hub enforces. Used to validate the addon before submitting it to Mozilla for signing. Runs both locally and in CI jobs.npm run get-version
: Tries to determine the target version number of browser extension builds. If the current git SHA is tagged with our semantic versioning scheme (v1.2.3
), outputs that number without thev
prefix (1.2.3
) as the desired version. Otherwise falls back to using the version defined inpackage.json
. Intended to be used in CI jobs.
Feel free to contribute a feature or bug fix by opening a pull request. If you discover any problems or have any suggestions, please open a GitHub Issue.
Please note that this is a side project for me, so it may take some time (possibly weeks) to get a response to your PR or Issue.
This project was inspired by https://github.com/JeroenVdb/streamdeck-googlemeet.
Neither this app nor its creator are affiliated with or endorsed by Google. The Google Meet name and logo are the exclusive property of Google.
Fonts for the actions and keys utilize rendered characters from the Noto Emoji
and Noto Color Emoji
fonts, under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)