Skip to content

Instantly share code, notes, and snippets.

@mohno007
Last active December 8, 2021 07:33
Show Gist options
  • Save mohno007/d4947babdfad47b2fd4cd5e68e798cd1 to your computer and use it in GitHub Desktop.
Save mohno007/d4947babdfad47b2fd4cd5e68e798cd1 to your computer and use it in GitHub Desktop.

Google Meet Push-to-Talk

Google Meetで、トランシーバやDiscordの同等機能のようにキーを押している間だけ通話ができるようにする拡張機能です。

This browser extension allow you to unmute a microphone while you are pressing a key. (like a transceiver or Discord Push-to-talk feature)

How to install

  1. Install one of these extensions you like in order to execute UserScript.
  2. Open this link: https://gist.github.com/mohno007/d4947babdfad47b2fd4cd5e68e798cd1/raw/google_meet_push_to_talk.user.js

How to use

Alt key (Option key for macOS) is default unmute key.

  • Unmute while pressing key
    • If you press and hold unmute key, a microphone will be unmuted while key is pressed.
  • Unmute / Mute switching
    • If you release unmute key within 0.1 sec, a microphone will be unmuted after the release of key.
// ==UserScript==
// @name Google Meet Push-to-talk
// @namespace https://gist.github.com/mohno007/d4947babdfad47b2fd4cd5e68e798cd1
// @version 0.2.3
// @description Push-to-talk for Google Meet
// @author mohno007
// @match https://meet.google.com/*
// @license CC0-1.0
// @grant none
// @downloadURL https://gist.github.com/mohno007/d4947babdfad47b2fd4cd5e68e798cd1/raw/google_meet_push_to_talk.user.js
// @updateURL https://gist.github.com/mohno007/d4947babdfad47b2fd4cd5e68e798cd1/raw/google_meet_push_to_talk.user.js
// ==/UserScript==
(function main() {
'use strict';
const micOn = new Audio('data:audio/x-wav;base64,UklGRrIBAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YY4BAACHp7esjGVJRlyBpbeuj2lLRVl+orawk2xNRVZ6n7Wxlm9PRVR2nLSzmXNSRVJzmbKznHdURVBwlrC0nnpXRk5skq60oX1aR01pj6y0o4FdSExmi6m0pYRgSktjiKezp4dkTEthhKSyqItnTktfgaGxqo5qUEtdfZ6wqpBuU0tbepuuq5NxVUxZd5itq5V1WE1YdZWrrJd4W05XcpKoq5l7Xk9Wb4+mqpt9YVFWbYujqpyAZFNWa4ihqZ2DZ1VWaYWep56FaldXaIObpp6HbFpXZoCYpJ6KcFxYZX2Wop6Lcl9ZZXuToJ6NdWFbZHmQn52Od2RcZHeNnJyPemZeZHaLmpuQfGlgZHSIl5qQfWtiZXOGlZmQf25kZnKEkpeQgHBmZ3KCkJWPgnJoaHKAjpOPg3RranJ/i5GOhHZtbHJ+iY+NhHhvbXJ8h42MhHpxb3N8hYuKhHt0cXR7g4iJhHx1c3V7goaHg314dXZ7gYSFg355d3h7f4ODgX57eXl8f4GBgH58e3t8fn9/f359fQ==');
const micOff = new Audio('data:audio/x-wav;base64,UklGRrYBAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YZEBAACDlKWxt7auoY98aFdLRUVMWWp+kaKvtrawpJJ/bFpNRkVLVmd6jp+ttbaxppaDb15QR0VKVWR3ipuqs7axqJmGc2FSSUZJU2FzhpinsbSyqZuKd2VWTEdJUl9wg5SkrrOyqp2NemhZTkpKUV1tf5Ggq7Gwqp+PfWxdUUtLUVxrfI2dqK+vqp+RgXBhVU5NUVtpeYqZpautqaCTg3NkWFFPUltndoaVoamrqKGVhndoXFRRVFtmdIORnaWop6CViHlsYFhUVltlcoCOmaGlpZ+WinxvZFtXWF1mcX2KlZ2iop6Wi39yaF9bW19mcHuHkpqen5yVjIF2a2NfXmFnb3qFjpaanJmUjIJ4b2diYWNob3iCi5KXmJeSi4N6cmtmZWZqcHiAh46TlZSRi4R8dW9raGlscXd+hYuPkZCOiYR+d3JubG1vcnd8goeLjY2LiIN+enVycHBydHh8gYSHiYmIhYJ/e3h2dHR1d3l8f4KDhIWEg4F/fXt6eHh5ent8foCAgYGAgH9+fX18fHx9fX19fgA=');
micOn.volume = 0.4;
micOff.volume = 0.4;
// 設定
const isPushToTalkKey = (ev) => {
// TBD Store config in LocalStorage
// Example:
// return ev.altKey && ev.key == 'm';
return ev.key === 'Alt';
};
const delay = 100;
const micOnThreshold = 100;
const findOldMuteButton = () => document.querySelector('div[role="button"][data-is-muted]');
const findNewMuteButton = () => document.querySelector('button[data-is-muted]');
// 通話中かどうかの判定に使っている
const talking = document.querySelectorAll('a[href^="https://accounts.google.com/AccountChooser"').length === 0;
if (!talking) {
setTimeout(main, 1000);
return;
}
const muteButton = [
findOldMuteButton(),
findNewMuteButton(),
].find(e => e != null);
if (! muteButton?.dataset) {
setTimeout(main, 200);
return;
}
const mute = () => {
if (muteButton.dataset.isMuted === "false") {
micOff.play();
muteButton.click();
}
};
const unmute = () => {
if (muteButton.dataset.isMuted === "true") {
micOn.play();
muteButton.click();
}
};
// 起動時にミュートにする
mute();
let timeoutId;
let keydownTime = +new Date();
window.addEventListener('keydown', (ev) => {
if (isPushToTalkKey(ev)) {
if (muteButton.dataset.isMuted === "true") keydownTime = +new Date();
if (timeoutId !== undefined) clearTimeout(timeoutId);
unmute();
}
});
window.addEventListener('keyup', (ev) => {
if (isPushToTalkKey(ev)) {
if (timeoutId !== undefined) clearTimeout(timeoutId);
const currentTime = +new Date();
if ((currentTime - keydownTime) <= micOnThreshold) return;
timeoutId = setTimeout(() => mute(), delay);
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment