拍手切换暗/亮模式
这篇文章最初发表在我的博客上
几天前,我们在Netlify 应用上发布了暗黑模式测试版。虽然我们仍在不断改进,但目前只能通过Netlify 实验室以及用户设置来使用。
尽管到达那里不需要点击很多次,但对我来说感觉太多了,在等待在导航中轻松访问它时,我想知道......如果能够通过拍手来切换它,就像一些家庭自动化设备一样,那不是很有趣吗?
因此,我花了周末的一部分时间研究如何构建它,最终使用 TensorFlow.js 构建了一个 Chrome 扩展程序和一个用我拍手样本训练的模型,可以打开/关闭暗模式!
结果如下:
有趣!!!😃或者至少对我来说...
所以,下面就是我的做法。
训练模型
首先,我训练了模型,以确保能够识别拍手的声音。为了更轻松、更快速地完成训练,我使用了Teachable Machine平台,更具体地说,我启动了一个音频项目。
第一部分是录制你当前的背景声音。然后,你可以创建多个“类”,用于录制你想在项目中使用的活动的声音样本,在本例中是拍手的声音。
一般来说,如果我知道我将在有更多种类声音的环境中使用这个模型,我会为更多的类别录制样本。
例如,我还录制了语音样本,以便模型能够识别语音的“样子”,而不会将其误认为是拍手。
完成样本记录后,您可以继续训练模型,预览其是否按预期工作并将其导出以在您的代码中使用它。
构建 Chrome 扩展程序
我不会详细介绍如何构建 Chrome 扩展程序,因为有很多不同的选项,但以下是我为自己所做的。
您至少需要一个manifest.json
包含有关您的扩展的详细信息的文件。
{
"name": "Dark mode clap extension",
"description": "Toggle dark mode by clapping your hands!",
"version": "1.0",
"manifest_version": 3,
"permissions": ["storage", "activeTab"],
"action": {
"default_icon": {
"16": "/images/dark_mode16.png",
"32": "/images/dark_mode32.png",
"48": "/images/dark_mode48.png",
"128": "/images/dark_mode128.png"
}
},
"icons": {
"16": "/images/dark_mode16.png",
"32": "/images/dark_mode32.png",
"48": "/images/dark_mode48.png",
"128": "/images/dark_mode128.png"
},
"content_scripts": [
{
"js": ["content.js"],
"matches": ["https://app.netlify.com/*"],
"all_frames": true
}
]
}
该项目最重要的部分是权限和内容脚本。
内容脚本
内容脚本是在网页上下文中运行的文件,因此它们可以访问浏览器当前正在访问的页面。
根据文件中的配置manifest.json
,这将在任何选项卡或仅特定选项卡上触发。由于我添加了参数"matches": ["https://app.netlify.com/*"],
,因此仅当我使用 Netlify 应用时才会触发。
然后,我可以开始触发专用于声音检测的代码。
设置 TensorFlow.js 来检测声音
使用 TensorFlow.js 时,我通常会将模型导出为文件保存在自己的机器上,但这次我决定使用另一种方式,将其上传到 Google Cloud。这样,就可以通过 URL 访问它了。
对于代码示例,当您导出模型时,Teachable 机器上会提供一个示例,但基本上,您需要从创建模型开始:
const URL = SPEECH_MODEL_TFHUB_URL; //URL of your model uploaded on Google Cloud.
const recognizer = await createModel();
async function createModel() {
const checkpointURL = URL + "model.json";
const metadataURL = URL + "metadata.json"; // model metadata
const recognizer = speechCommands.create(
"BROWSER_FFT",
undefined,
checkpointURL,
metadataURL
);
await recognizer.ensureModelLoaded();
return recognizer;
}
完成后,您可以开始实时预测:
const classLabels = recognizer.wordLabels(); // An array containing the classes trained. In my case ['Background noise', 'Clap', 'Speech']
recognizer.listen(
(result) => {
const scores = result.scores; // will be an array of floating-point numbers between 0 and 1 representing the probability for each class
const predictionIndex = scores.indexOf(Math.max(...scores)); // get the max value in the array because it represents the highest probability
const prediction = classLabels[predictionIndex]; // Look for this value in the array of trained classes
console.log(prediction);
},
{
includeSpectrogram: false,
probabilityThreshold: 0.75,
invokeCallbackOnNoiseAndUnknown: true,
overlapFactor: 0.5,
}
);
如果一切顺利,当此代码运行时,它应该根据实时音频数据的预测记录“背景噪音”,“拍手”或“语音”。
现在,为了切换 Netlify 的暗黑模式,我console.log
用一些小逻辑替换了之前的语句。目前暗黑模式的实现方式是tw-dark
在 body 上添加一个 class。
if (prediction === "Clap") {
if (document.body.classList.contains("tw-dark")) {
document.body.classList.remove("tw-dark");
localStorage.setItem("nf-theme", "light");
} else {
document.body.classList.add("tw-dark");
localStorage.setItem("nf-theme", "dark");
}
}
我还更新了 localStorage 中的值,以便将其保留下来。
安装扩展
为了能够测试此代码是否有效,您必须在浏览器中安装扩展程序。
(在此之前,您可能必须捆绑您的扩展,具体取决于您使用的工具。)
要安装它,请遵循以下步骤:
- 访问
chrome://extensions
Developer mode
位于页面右上角的切换按钮- 单击
Load unpacked
并选择包含捆绑扩展的文件夹
如果一切顺利,您应该访问您想要运行扩展程序的任何页面,它应该请求麦克风权限才能检测实时音频,并开始预测!
--
就是这样!总的来说,这个项目其实跟切换暗黑模式没什么关系,但我一直想学习如何在 Chrome 扩展程序中使用 TensorFlow.js,所以这看起来是个绝佳的机会!😃
如果您想查看代码,这里是 repo!
现在,我可以把它从我永无止境的清单上划掉了。✅
文章来源:https://dev.to/devdevcharlie/toggle-dark-light-mode-by-clapping-your-hands-li7