Créer un bouton de sourdine matériel dans Zoom

Récemment, Instagram m'a montré une publicité pour un bouton de désactivation du zoom dédié, qui s'est avéré très pertinent pour moi.







Oui, j'appelle Zoom tous les jours. Oui, j'ai un enfant qui interfère souvent avec ces appels. Algorithme de livraison d'annonces Instagram, vous avez gagné, j'ai besoin de ce bouton.



Mais j'ai des préjugés. Instagram annonce un projet avec Kickstarter. De plus, je ne veux pas contribuer aux revenus publicitaires de Facebook même en cliquant sur cette vidéo. L' expression de Jenny Odell «Il n'y a pas d'heures gratuites» décrit pleinement mon point de vue sur la qualité des produits dans les publicités Instagram. De plus, ma limite de financement pour les projets Kickstarter est presque épuisée.



J'ai soutenu de nombreux projets sur Kickstarter, et parfois le résultat de ces projets m'a rappelé le hamburger que Michael Douglas avait dans le film "I've Enough!"





Alors, mettons en place un tel bouton nous-mêmes.



La première chose à laquelle je dois penser est de savoir sur quel bouton voudrais-je appuyer?



J'adore les claviers équipés de commutateurs Cherry MX. Il existe trois types de commutateurs mécaniques: linéaires, tactiles et cliquables. Linéaire - Le type de commutateur le plus simple qui se déplace de haut en bas sans presque aucune rétroaction. Les commutateurs tactiles ont une saillie au milieu de la course qui vous permet de sentir quand une touche est enfoncée. Et les commutateurs cliquables ont un retour tactile plus fort ET produisent un clic audible lorsqu'ils sont enfoncés.



Normalement, nous achèterions un testeur de commutateur pour déterminer quel type nous répond . , et nous demanderions également à nos collègues quel son doit produire le clavier pour ne pas nous tuer. Mais nous sommes au milieu de la pandémie COVID, donc il n'y a pas de collègues autour! Optez pour un interrupteur Cherry MX Blue avec un retour tactile confortable et extrêmement fort. Le site Web de Cherry MX appelle ce commutateur "cliquable et visible", mais cela reste très peu dit.





Ça a l'air joli, mais tu pourrais penser à quelque chose de mieux. Si je suis heureux de frapper le commutateur Cherry MX Blue, ne serait-il pas encore plus agréable de frapper le Cherry MX Blue comique?



Et c'est le Big Switch de Novelkeys .





Il est 4 fois plus grand dans chaque dimension et 64 fois plus grand en volume qu'un interrupteur conventionnel. Il a même une énorme casquette!





Malheureusement, le Big Switch n'est pas vendu dans un boîtier, j'ai donc dû utiliser l'impression 3D. Un bel étui a été trouvé sur Thingiverse: NovelKeys Big Switch Case . Cela vaut toujours la peine de chercher des remix au cas où quelqu'un voudrait améliorer le design original. Dans ce cas, il y avait un remix qui a ajouté un compartiment pour le Pro Micro, et le commutateur est plus serré, alors je l'ai imprimé.





Maintenant que nous avons un boîtier, nous avons besoin d'une carte que nous y insérons et fixons au commutateur.



Le Pro Micro dispose d'une puce ATmega32U4 pour émuler un périphérique USB HID tel qu'un clavier USB. De plus, cette carte est petite.





Il y a deux contacts métalliques au bas du grand interrupteur.





Lorsqu'une touche est enfoncée à l'intérieur de l'interrupteur, un circuit est fermé entre ces deux contacts.





Jetons un coup d'œil à la disposition des broches de Pro Micro:





Vous pouvez connecter GND à une broche métallique et la broche 2 à l'autre. La broche 2 est une broche d'E / S numérique qui lit HIGH lorsqu'une touche est enfoncée et LOW quand ce n'est pas le cas.



Ce serait également formidable d'avoir une sorte d'indicateur visuel de l'état du Mute, afin que vous puissiez ajouter une LED.



J'ai commandé une LED de 10 mm:





Et une résistance de 220 ohms:





La jambe longue des LED se connecte à PWR et la jambe courte se connecte à GND. Nous allons insérer une résistance entre la longue jambe et l'autre broche pour réduire la quantité de courant. J'ai sélectionné la broche 9 en bas du tableau. J'ai connecté la jambe courte à GND. J'ai trouvé cette page sur les LED et les résistances utile .



J'ai soudé ce fil 20 AWG entre la carte et l'interrupteur:





Le résultat est la construction suivante:





Remplissons simplement tout cela dans notre étui imprimé:





Nous devons maintenant écrire le code.



J'ai commencé avec le code que Sparkfun a écrit pour créer un énorme bouton d'enregistrement et je l'ai un peu modifié.



Le principe est le suivant: lorsque vous appuyez sur une touche, il envoie un raccourci clavier Zoom pour activer et désactiver le son (sur Mac c'est Cmd-Shift-A). Vous devrez modifier les paramètres de zoom pour que ce raccourci clavier soit reconnu même lorsque le zoom est flou. Cochez la case Activer le raccourci global :





Nous voulons également allumer ou éteindre la LED après chaque pression de touche. J'ai décidé que la LED serait analogue à la lumière «On Air» - lorsque la LED bleue est allumée, mon son est allumé et les gens entendent ce que je dis.



Mais si vous allumez et éteignez simplement le voyant à chaque fois que vous appuyez sur une touche, comment rester synchronisé avec l'état Muet dans le zoom lui-même?



L'avantage du Pro Micro est qu'il dispose également d'une connexion série. Il est généralement utilisé pour imprimer des informations de débogage dans l'IDE Arduino, mais nous pouvons l'utiliser pour le maintenir synchronisé avec l'état d'activation de l'audio dans Zoom.



Voici le code que nous chargeons dans Pro Micro lui-même:



#include "Keyboard.h"

// OS parameters
typedef enum {
  LINUX,
  WINDOWS,
  MAC
} os_types;

// Change this to your operating system
const os_types OS = MAC;

// Pins
const int btn_pin = 2;
const int led_pin = 9;

// Constants
const int debounce_delay = 50;              // ms

// Globals
int btn_state = HIGH;
int btn_prev = HIGH;
unsigned long last_debounce_time = 0;
int os_ctrl;
int led_state = LOW;

void setup() {

  Serial.begin(57600); // opens serial port, sets data rate to 57600 bps
  
  // Set up LED and button pins
  pinMode(btn_pin, INPUT_PULLUP);  // Set the button as an input
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, led_state);

  // Begin keyboard
  Keyboard.begin();

  // Switch to correct control/command key
  switch(OS){
    case LINUX:
    case WINDOWS:
      os_ctrl = KEY_LEFT_CTRL;
      break;
    case MAC:
      os_ctrl = KEY_LEFT_GUI;
      break;
    default:
      os_ctrl = KEY_LEFT_CTRL;
      break;
  }

  // Get initial timestamp

  Serial.println("started");
  
}

void loop() {

  // Read current state of the button
  int btn_read = digitalRead(btn_pin);

  // Remember when the button changed states
  if ( btn_read != btn_prev ) {
    last_debounce_time = millis();
  }

  // Wait before checking the state of the button again
  if ( millis() > (last_debounce_time + debounce_delay) ) {
    if ( btn_read != btn_state ) {
      btn_state = btn_read;
      if ( btn_state == LOW ) {

        // Send cmd+shift+a
        Keyboard.press(KEY_LEFT_SHIFT);
        Keyboard.press(os_ctrl);
        Keyboard.press('a');
        delay(100);
        Keyboard.releaseAll();

        Serial.println("pressed");

        if (led_state == LOW) {
          led_state = HIGH;
        } else {
          led_state = LOW;
        }
        digitalWrite(led_pin, led_state);

      }
    }
  }

  // Remember the previous button position for next loop()
  btn_prev = btn_read;

  if (Serial.available() > 0) {

    String incomingString = Serial.readStringUntil('\n');

    if (incomingString == "muted") {
      led_state = LOW;
    } else if (incomingString == "unmuted") {
      led_state = HIGH;      
    }

    digitalWrite(led_pin, led_state);
    
  }
  
}
      
      





Ensuite, nous pouvons ajouter un Applescript pour signaler l'état actuel du zoom. J'ai trouvé un plug-in Zoom Streamdeck qui contenait l'Applescript original et je l'ai modifié pour indiquer si Zoom est ouvert et quel est l'état de son son. J'ai également modifié le script pour générer JSON.



set zoomStatus to "closed"
set muteStatus to "disabled"
tell application "System Events"
	if exists (window 1 of process "zoom.us") then
		set zoomStatus to "open"
		tell application process "zoom.us"
			if exists (menu bar item "Meeting" of menu bar 1) then
				set zoomStatus to "call"
				if exists (menu item "Mute audio" of menu 1 of menu bar item "Meeting" of menu bar 1) then
					set muteStatus to "unmuted"
				else
					set muteStatus to "muted"
				end if
			end if
		end tell
	end if
end tell

copy "{\"mute\":\"" & (muteStatus as text) & "\",\"status\":\"" & (zoomStatus as text) & "\"}" to stdout
      
      





Si nous l'exécutons maintenant lors d'un appel à Zoom, il affichera quelque chose comme ceci:



$ osascript get-zoom-status.scpt
{"mute":"muted","status":"call"}
      
      





Puis j'ai écrit une petite application dans Node, utilisée comme intermédiaire entre Pro Micro et ce script:



const { exec } = require('child_process');

const SerialPort = require('serialport');
const Readline = require('@serialport/parser-readline');
const port = new SerialPort('/dev/tty.usbmodemHIDPC1', {
    baudRate: 57600
});

var checkStatus = function() {
    console.log('Checking status...');
    exec('osascript get-zoom-status.scpt', (error, stdout, stderr) => {

        if (error) {
            console.error(`exec error: ${error}`);
            return;
        }

        var status = JSON.parse(stdout);
        if (status.mute == 'unmuted') {
            port.write('unmuted');
        } else {
            port.write('muted');
        }

    });
}

const parser = port.pipe(new Readline({ delimiter: '\r\n' }))
parser.on('data', function (data) {
    if (data == "pressed") {
        console.log('Button pressed.');
        checkStatus();
    }
})

checkStatus();
setInterval(checkStatus, 30000);
      
      





Ce script fait deux choses. Lorsque le bouton est enfoncé, il envoie une commande «enfoncée» à la carte Pro Micro via le port série, qui exécute Applescript pour déterminer l'état actuel de l'audio dans Zoom. Il envoie ensuite une commande «bip désactivé» ou «bip activé» à la carte Pro Micro, provoquant le passage de la LED à l'état approprié. J'ai également créé une minuterie qui exécute un script toutes les 30 secondes au cas où je couperais ou réactiverais accidentellement le son via l'interface Zoom plutôt que le bouton, sinon l'état ne se mettra à jour que lorsque le bouton est enfoncé.



Voici à quoi ressemble le bouton lorsqu'il est utilisé dans un appel via Zoom:





Veuillez soutenir mon Kickstarter - je plaisante, je n'ai pas de Kickstarter, mais j'espère que vous pourrez maintenant en créer un vous-même.






Publicité



Commandez un serveur et commencez à travailler tout de suite! Création de VDS de n'importe quelle configuration en une minute. Épique :)






All Articles