65.9K
CodeProject 正在变化。 阅读更多。
Home

索尼 N - 您可以编程的智能无线耳机

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2017 年 2 月 23 日

CPOL

12分钟阅读

viewsIcon

17951

为 Nigel 编写自己的片段,使用 Future Lab Program。

我花了很多时间使用无线耳机与我的手机。事实是,没有人想在开车、遛狗、在跑步机上跑步或在厨房里工作时,把手机举到耳朵边。更糟糕的是,您不希望耳机线挂在耳朵外面,被什么东西绊住,从而干扰您正在手机上进行的任何操作。最重要的是,当今大多数无线耳机只是一个简单的蓝牙扬声器,除了放大手机的各种操作外,没有任何实际功能。

作为一名消费者,我正在寻找一款能够从根本上提升我的移动通信和计算体验的智能手机配件。我认为索尼的 N 产品非常有潜力。

N – 名称的含义?

N?索尼正在发布一款名为“N?”的设备。嗯,可以说是……在一个公司投入巨资押注各种设备并需要确保下一部手机或平板电脑成功发布的时代,如何在没有市场调研的情况下取得成功?更妙的是,软件行业已经拥抱了敏捷开发方法,为什么不能将类似的方法应用于硬件呢?这正是索尼正在做的。

N 是一个完全成熟的原型,软件开发者可以上手进行测试和探索,以获取索尼的反馈和市场调研。它并不是一款功能齐全的设备,并且明显缺少一些可能添加的特性,使其成为一款完整的手机配件。索尼省略了一些功能也就不足为奇了,这样他们的工程师就可以迭代并继续改进设备。

为了完成敏捷硬件开发的理念,索尼甚至还没有为该产品给出一个完整的公开代号。作为技术爱好者,我们听过“Chicago”、“<INSERT OTHER CODENAMES>”之类的代号,但这款设备只标为“N”,距离一个酷炫的代号仅几个字符。但这正是重点……如果反馈不强,开发者也不热衷于使用该设备,那么它就可以被悄悄停产,索尼可以迅速转向构建下一个创新设备。

“N”看起来怎么样?

以下是我收到设备时开箱的体验。它装在一个简单的无标记白色盒子里,打开后我发现了一个顶面带有标签的圆柱形盒子。

这是一个很棒的初步印象,但里面有什么呢?我取下了顶部,或者说我认为是顶部的东西,然后发现了这个。

N 设备是一款马蹄形耳机,戴在颈部。我一直称它为颈带,我以前也见过类似的无线耳机,我担心没有有线耳机可以连接到马蹄形部分。就在那时,我发现圆盒还有另一层。当我把它拿起来时,我发现了以下东西。

有一个 USB 电源适配器和一些看起来很奇怪的耳塞。我过去几年时不时地使用 Apple Ear Pods,而这些看起来完全不像 Ear Pods!

呃,有人忘了关耳机的后盖,因为我能看穿它。我读完了说明书,将耳机插入颈带并开机。大约 60 秒后,N 启动了,我把它戴在脖子上。耳机佩戴起来很有趣,它夹在我的耳垂上,让我在没有声音通过设备播放时也能听到周围的一切。

我在 iPhone 上下载并安装了 Future Lab Program N 应用程序,并通过一个简单的教程了解了该设备的这些很酷的功能。

    

N 有何不同?

有一个应用程序需要安装在你的手机上,用于连接和操作耳机。我将该应用程序下载到我的 iPhone 6s Plus 上,并通过其教程开始学习如何使用该设备。我尝试了一些内置的新闻频道,它们允许我获取来自互联网源的天气和最新信息,这些信息通过我的手机无线连接访问。我可以通过说“Listen Up Nigel”并发出各种语音命令来使用耳机进行语音控制。当我在厨房里走动,或者遛狗,甚至在车里开车时,我的妻子和孩子们开始觉得我对着“Nigel”说话很有趣。

我推断 N 不仅仅是一个带有酷炫耳机的颈带,而是一个完整的计算体验,带有我可以访问的摄像头和驱动器。我可以编写 JavaScript 扩展,将其加载到设备上以实现更多功能。这就是我想要的:一件富有远见的装备,我可以对其进行软件扩展,使其成为我自己的,并极大地改善我的移动体验。

我会开始在手机上播放音乐或播客,然后可以直接通过耳机收听,正如您所预期的那样。当有人想开始交谈时,这些通透的耳塞非常方便。您可以听得很清楚,我将之比作一种感觉,仿佛附近有一个响亮的立体声在播放,而您仍然能听到房间里的人的声音。

另一方面,N 不知道如何开始或管理电话。作为一个日常通话耳机,它不提供手机上的电话应用程序的任何功能……目前还不行。它确实有一个小的驱动器,用于存储您指示 Nigel 通过发出“photo”命令来捕获的图片。您还可以指示 Nigel“开始间隔拍照”,相机将每分钟捕获一张照片,直到被指示停止。这是一个有趣的概念:拍摄我所做的一切,并在会话结束时,通过从耳机内置驱动器下载照片来回顾 Nigel 捕获的内容。

要访问驱动器内容,除了使用语音外,您还需要使用提供的 micro-USB 线将耳机连接到您的 PC 或 Mac。耳机在您的计算机上显示为一个额外的驱动器,您可以对该驱动器执行正常的文件夹管理操作。除了照片,驱动器还可以存储您喜欢的 mp3 格式音乐文件的本地副本,方便播放,无需连接手机。当然,您可以像普通的蓝牙耳机一样从手机流式传输音乐。

开始开发

这是该设备的亮点,编写您自己的“片段”,让 Nigel 服从您的命令并为您完成一些工作。首先,您需要注册 Future Lab Program 并从其 入门页面 下载 SDK。SDK 是一个 NodeJS 包,您需要使用 npm 下载并配置它。入门页面上的说明将引导您将库放置在磁盘上,并构建一个基于 Electron 的开发工具,称为“Segment Developer Tools”。

安装完成后,您就可以开始编写 JSON 和 JavaScript 文件来定义您的片段了。在本示例中,我将编写一个片段,从 MSDN Web 开发博客中读取最新的三条标题。要开始,您应该为您的片段创建一个新文件夹,其中包含两个子文件夹:app 和 res。App 将包含运行您的应用程序的代码,res 将包含有关片段的 JSON 配置文件。

在文件夹的根级别,您需要创建三个文件来定义您的应用程序。

  • LaunchRules.json – 一组关于 N 用户如何启动您的片段的定义。
  • Manifest.json – 片段元数据,例如片段的名称、作者、描述和版本信息。
  • index.html – 包含指向您的片段需要运行的 JavaScript 文件的指针。

LaunchRules.json 文件的格式非常简单,对于我只想用一个简单的“check web dev blog”命令来启动该片段的这个片段,我可以这样写:

{
    "voicePattern": [{
            "domain": "CUSTOMAPP",
            "name": ["web dev blog"]
    }]
}

Domain 必须是“CUSTOMAPP”,但 name 数组包含启动该片段的命令名称。此值应全部小写。

接下来,Manifest.json 需要包含一些关于该片段的简单信息。对于这个博客阅读器,我写了以下内容:

{
    "package": "MSDN.Blog.WebDev",
    "manifestVersion": 1,
    "name": "MSDN WebDev Blog Latest",
    "shortName": "MSDN_WebDev_Latest",
    "author": {
        "name": "Jeffrey T. Fritz"
    },
    "description": "The latest news from the MSDN Web Development Blog",
    "version": 1,
    "versionName": "1.0.2"

}

这是关于该片段的最小信息量。值得注意的是,“manifestVersion”必须是 1,“version”必须是整数。我已经递增了“versionName”字符串,因为我已经发现了 2 个 bug 并在我的演示代码中进行了修补。

让我们配置 index.html 文件,使其包含指向我应用程序 JavaScript 文件的指针。这是一个简单的 HTML 文件,仅包含引用我的 JavaScript 的脚本元素。

<html>
    <head>
        <script type="text/javascript" src="app/lib/jquery-2.1.4.min.js"></script>
        <script type="text/javascript" src="app/blog.js"></script>
    </head>
    <body>
        <!-- Not used -->
    </body>
</html>

接下来,我们需要开始编写一些资源来配置该片段。在 res 文件夹中,我们需要创建一个“scripts”子文件夹,并在该文件夹中放置一个“scripts.json”文件。此文件定义了片段启动和结束时的音乐、声音或“脚本”。一个简单的默认文件包含以下条目,它们会在设备上触发一些不错的开场和结尾音乐。

{
  "segmentStart": {
    "common": "start segment"
  },
  "segmentEnd": {
    "common": "stop segment"
  }
}

最后两块配置将放在 res/settings 文件夹中。这两个文件是 schema.jsondefaultValues.jsonschema.json 定义了应用程序的各种设置,包括在移动应用程序上显示的描述。defaultValues.json 定义了这些设置的默认值。我的 schema.json 包含以下内容:

{
  "schema": {
    "scope": "MSDN.Blog.WebDev",
    "version": "1.0",
    "settings": [{
        "key": "description",
        "displayName": "A summary of the latest news from the MSDN Web Development Blog.\nThis segment starts with the following voice commands:\n - Start web dev blog\n - Check web dev blog\n\njeff@jeffreyfritz.com",
        "layout": "description"
    }]
  }
}

您可以在此文件中应用其他设置,以捕获 N 移动应用程序中片段配置页面上的其他设置。与此模式对应的 defaultValues 是:

{
  "defaultValues": {
    "scope": "MSDN.Blog.WebDev",
    "version": "1.0",
    "settings": { }
  }
}

这两个文件中的 scope 应该与 Manifest.json 中定义的包名称匹配。配置了这些元数据并保存了启动信息后,我就可以开始在 app 文件夹中编写代码了。为了简化使用 AJAX 和 Promises 获取数据,我复制了一个 jQuery 副本并将其放在我的 app 文件夹中。接下来,我开始编写一个名为 blog.js 的脚本文件,其中包含我获取和读取博客文章的所有业务逻辑。

在 blog.js 文件中,我们可以引用并使用 API 暴露的主要对象“da”。我配置了两个主要的事件处理程序:segment.onpreprocess 和 segment.onstart。在 onpreprocess 事件中,我编写了一些代码来访问博客的 RSS feed,并将条目解析为 JavaScript 对象,我可以在 onstart 事件中指示 Nigel 读取这些对象。我的 onpreprocess 处理程序看起来像这样:

da.segment.onpreprocess = function(trigger, args) {
    
    var blogData = new BlogData(); 
    blogData.load().done(function(errorCode) {

        if (errorCode == 0) {

            da.startSegment(null, {
                args: {
                    blog: blogData.entries
                }
            });

        }

    });

}

我的 BlogData 对象知道如何使用 jQuery AJAX 获取 RSS 并将该对象作为一系列项返回到 blogData.entries 属性中。您可以在附件的示例代码下载中查看该代码。onstart 处理程序则有些有趣,因为我们可以开始使用语音合成器向用户朗读文本。

da.segment.onstart = function (trigger, args) {
    var synthesis = da.SpeechSynthesis.getInstance();

    synthesis.speak(args.blog.length + " new items from the M S D N Web Development Blog", {
        onend: function() {
            SpeakNextStory(synthesis, args.blog);
        }
    });

};

var storyCounter = 0;

function SpeakNextStory(synthesis, blogEntries) {

    if (storyCounter >= blogEntries.length) { 
        synthesis.speak("That's all from the M S D N Web Development Blog", {
            onend: function(){
                console.log("Done reading stories");
                da.stopSegment();
            }
        });
    } else {
        synthesis.speak(blogEntries[storyCounter].title + blogEntries[storyCounter].description, {
            onend: function(){
                console.log("Story " + storyCounter);
                storyCounter++;
                SpeakNextStory(synthesis, blogEntries);
            }
        });
         
    }

}

我通过 da.SpeechSynthesis.getInstance() 调用获取了语音合成器的实例,并使用该 API 中内置的 Promise 来确保我的代码在朗读完每个句子后运行。我通过链接调用 SpeakNextStory 方法,以允许以这种递归 JavaScript Promise 代码结构来组织代码。一旦第三个故事被朗读完毕,就会朗读一个结束语,然后调用 stopSegment 方法。

StopSegment 向设备发出信号,表示该片段已完成处理,应被解除分配。

测试片段

使用 Segment Developer Tools 应用程序,我可以点击“Segment List”部分上方的蓝色“Add”按钮,浏览到我的代码文件夹,并将我的片段添加到列表中。您可以在下面的图像中看到添加我的片段时的样子。

我用箭头指向该片段的 Launch 按钮,因为我可以点击它并收听设备将如何解释和使用我的应用程序。在“Debug”菜单项下有一个“Segment DevTools”选项,它允许我使用熟悉的 Chrome JavaScript 调试工具来调试我的片段中的 JavaScript 代码,以便测试和单步执行我的代码。

一旦我的代码按我想要的方式工作,我就可以点击屏幕中间的“Export”按钮,将我的代码和配置编译成一个 CPK 文件,然后可以将其上传到 Future Lab Program 网站并在我的设备上激活。

点击左侧的“Developer Profile”链接,然后选择“Upload Applications”来查找并上传您的 CPK 文件到 Future Lab Program 网站。一旦上传,您将在“Manage Applications”区域看到它,如上图所示。您可以通过点击您的片段名称旁边的“Manage”按钮来请求将您的片段发布供公众使用。在“Test Applications”区域中,我可以在移动应用程序的“Segments”区域中找到我的 MSDN Blog 片段。

然后,我可以激活它,并开始让我的 N 设备“check web dev blog”来报告该博客的最后三篇文章。

摘要

我们了解了索尼令人兴奋的新 Future Lab Program 以及如何注册参与该计划。下载 NodeJS SDK 并使用模拟器调试将在设备上运行的代码非常容易。如果您真的有兴趣参与,可以 从开发者网站向索尼申请借用硬件。注册索尼的 Future Lab Program,开始构建语音激活的应用程序,以改善您的移动计算体验。

© . All rights reserved.