Category: Amazon Polly*


Whooshkaa + Amazon Polly:结合阅读与收听,拓宽发布渠道

本文是特邀文章,由 Whooshkaa 的创始人兼 CEO Robert Loewenthal 撰写。

Whooshkaa 总部位于澳大利亚,提供创新的点播式音频播客平台,帮助出版商和广告商赢得听众。我们一直在尝试新的产品和方法,并将二者结合起来,为我们的客户开创全新的解决方案。

Amazon Polly 文本转语音 (TTS) 功能的采用就是极好的例证。很多顶级出版商、体育机构,以及澳大利亚最大的电信公司已在使用 Amazon Polly 来扩充其既有的发行方式。

这些传统信息提供商发现,客户现在不只需要阅读信息,还希望能够收听信息。借助 Amazon Polly TTS,Whooshkaa 让信息提供商能够用 48 种语音和 24 种语言向听众发布信息。

今年早些时候,Amazon Polly 为澳大利亚的主要全国性报纸《The Australian》提供语音版本。订阅者在驾车、锻炼或其他不方便阅读的情况下可以收听 Amazon Polly 朗读的新闻报道、食谱或体育赛事比分。

通过 Amazon Polly,Whooshkaa 的优秀合作伙伴可以方便地选择任何新闻报道,在几秒之内将文本转换为播客内容。我们还提供一些工具,可以合并多个报道,并通过更改口音、音调、速度和音量对声音进行自定义。

Whooshkaa 有庞大的发布网络,也就是说,听众可以选择多种方式来收听内容。最直接的选择是听众常用的播客应用程序。不过,因为 Whooshkaa 与 Facebook 存在独特的合作关系,我们的播客可以通过 Facebook 的音频播放器播放。我们的 Web 播放器可进行自定义,在 Twitter 上也受支持,实际上它可以嵌入任何网站。

我们相信,当这项技术成熟时,出版商能够以任何语言在世界上任何地方提供其新闻报道。新闻报道可以根据听众的偏好和需求进行自定义。

我们还与澳大利亚最大的电信公司 Telstra 和澳大利亚全国橄榄球联赛合作,通过任何联网的智能播音设备发布用户最爱球队的现场比分。用户可以直接向其设备询问当前比分,设备能够立即播报结果。

我们的开发人员 Christian Carlsson 认为,Amazon Polly TTS 的即时性和对各种语言的广泛支持可以为各类出版商带来无限机会。

“通过将功能强大的 Whooshkaa 平台与人工智能集成,我们现在可以在 30 秒内从文字创建完全自动化的播客内容,而这仅仅是开始。”Carlsson 说。

AFL 集成的技术实现

澳大利亚橄榄球联赛 (AFL) 希望粉丝们可以通过与智能播音设备进行语音互动来关注其最爱的球队。为此,Whooshkaa 需要创建一个 RSS 源,每两分钟更新一次,以提供最新结果。下面是我们实现方法的简单概图。

为触发 AFL 的 API 爬网 (其中包含我们需要的数据),我们开发了一个简单的 AWS Lambda 函数来调用 API。该 Whooshkaa API 提取数据、分析数据,然后将数据转换为语音,通过新创建的 RSS 源发布到 Amazon S3。

首先,我们编写 serverless.yml 文件,它负责每两分钟初始化一次请求。这没有什么出奇之处。

Serverless.yml:
createAFLFeeds:
 handler: api.createAFLFeeds
 events:
   - schedule:
       rate: rate(2 minutes)
       enabled: ${self:custom.${opt:stage}.ScheduledEvents}

这就会触发以下代码:

WhooshkaaAPI.js
createAFLFeeds() {
    return new Promise((resolve, reject) => {
      this.fetchAFLTeams().then(result => {
        for (const team of result) {
          this.createAFLFeedByTeamID(team['id']);
        }
      }, error => {
        console.log(error);
        reject(error);
      });
      resolve({message: "success"});
    });
}

接下来, createAFLFeedByTeamID 方法向我们的终端节点发送 POST 请求,终端节点执行以下操作:

  1. 从 AFL API 获取数据。为使此方法尽可能易读,数据标准化功能已分离到单独的 AFL 程序包。待分析数据由几个不同的条件确定。如果某个球队正在比赛或者在之前 24 小时内进行过比赛,则获取其比赛数据,否则默认获取该球队的最新新闻。
  2. 通过在 Amazon S3 中存储所返回数据的哈希,确保这些数据是新的。$this->publisher 也是一个抽象类,它包含三个不同存储适配器:本地、Whooshkaa S3 存储桶和 AFL S3 存储桶。我们使用本地适配器处理数据,使用 Whooshkaa S3 存储桶存储相应哈希,将生成的 RSS 源发布到 AFL S3 存储桶。
  3. 通过 Amazon Polly 获取文本并将其转换为音频流。您可以在 makeAudio 方法中看到我们如何处理某些字词,使之按我们的预期发音。例如,体育场馆 MCG 之前被理解成了“McGee”,于是我们改为让 Amazon Polly 逐个字母地读出来。
  4. 创建 RSS 源,将它发布到 AFL 的 S3 存储桶。
AFLController.php:
public function team(string $id)
{
    if (!$team = Team::findById($id)) {
        $this->response->errorNotFound('Invalid team ID.');
    }

    if ($team->isPlayingOrHasRecentlyPlayed()) {
        $story = $team->match;
    } else {
        $story = $team->news;
    }

    $this->publisher->setTeamId($id);
    $this->publisher->setStory($story->getStory());

    $hash = Hash::make($story, $this->publisher->getRemoteStorageAdapter());
    if ($hasBeenUpdated = $hash->hasBeenUpdated()) {
        $fileName = $this->publisher->getFileName();

        $audio = $this->makeAudio($story);
        $this->publisher->store($fileName, $audio->getContent());

        $feed = $this->makeFeed($team, $story);
        $this->publisher->store('feed.xml', $feed->getContent());

        $this->publisher->moveToCloud([$fileName, 'feed.xml']);
        $this->publisher->cleanUp();

        $hash->store();
    }

    return response([
        'rss' => $this->publisher->getRemoteUrl('feed.xml'),
        'updated' => $hasBeenUpdated,
    ]);
}

private function makeAudio($story)
{
   $polly = new Polly;
   $polly->setPhonemes(['live' => 'laɪve']);
   $polly->setProsody('AFL', ['rate' => 'fast']);
   $polly->setSayAs(['MCG' => 'spell-out']);

   $text = $story->getStory();
   // Trim the text to a maximum of 1500 characters.
   if (strlen($text) > 1499) {
       $text = $this->text->setText($text)->trimToWordBoundary(1499);
   }

   try {
       $audioStream = $polly->fetchAudioStream($text);
   }
   catch (\Exception $e) {
       $this->response->error($e->getMessage(), $e->getStatusCode());
   }

   return response()->make($audioStream)->header('Content-Type', 'audio/mpeg');
}

private function makeFeed(Team $team, $story)
{
   $feed = new Feed($this->publisher->getRemoteURL('feed.xml'));
   $feed->setTitle($team->getName() . "'s Official Live Feed");
   $feed->setDescription('An official live feed from the Australian Football League.');
   $feed->setLink('http://www.afl.com.au');
   $feed->setOwner('The Australian Football League', 'podcast@afl.com.au');
   $feed->setImage($team->getImage());
   $feed->appendElements([
       'itunes:subtitle' => "Follow {$team->getName()}'s Live Matches and Latest News",
       'itunes:explicit' => 'no',
       'language' => 'en-us',
       'lastBuildDate' => Carbon::now('UTC')->toRssString(),
       'ttl' => 2,
       'copyright' => 'The Australian Football League',
   ]);

   $feed->setCategories([
       'Sports & Recreation' => [
           'Professional',
       ]
   ]);

   $fileName = $this->publisher->getFileName();
   $metaData = $this->getMetaData($fileName);

   $item = $feed->addItem([
       'title' => $story->getTitle(),
       'link' => $story->getArticleURL(),
       'pubDate' => Carbon::now('UTC')->toRssString(),
       'itunes:duration' => $metaData['playtime_string'],
   ]);
   $item->appendDescription($story->getStory());
   $item->appendEnclosure($this->publisher->getRemoteUrl($fileName, true), $metaData['filesize'], $metaData['mime_type']);
   $item->append('itunes:image', null, ['href' => $team->getImage()]);
   $item->append('guid', $this->publisher->getGuid(), ['isPermaLink' => 'false']);

   return response()->make($feed->output())->header('Content-Type', 'text/xml');
}

《The Australian》“Daily News”的技术实现

The Australian 是 News Corp 旗下的报纸发行商。他们需要将每日 10 大头条新闻以音频形式提供给听众,并且要求头条新闻以播客形式每天更新五次。集成 Amazon Polly 让我们轻松实现了这些要求。下面是我们实现方法的简单概图。

此实现与 AFL 集成非常相似,但有一处不同。这次不生成 RSS 源,而是将播客发布到《The Australian》Whooshkaa 账户上的一栏指定节目。这样,内容几乎能够在 iTunes、Pocket Casts 或其他任何播客播放器中随即播放。

为了完成此实现,我们像之前在 AFL 实现中所做的那样,开发了一个 AWS Lambda 函数,这是因为我们需要在一天中几个特定时间触发“Daily News”终端节点。

Serverless.yml
createDailyNewsStory:
 handler: api.createDailyNewsStory
 events:
   - schedule:
       rate: cron(0 2,6,10,22 * * ? *)
       enabled: ${self:custom.${opt:stage}.ScheduledEvents}
   - schedule:
       rate: cron(30 14 * * ? *)
       enabled: ${self:custom.${opt:stage}.ScheduledEvents}
WhooshkaaAPI.js
createDailyNewsStory() {
 const options = {
   hostname: this.commonOptions.hostname,
   port: this.commonOptions.port,
   path: '/news-corp/daily-news',
   method: 'POST',
 };
 return new Promise((resolve, reject) => {
   this.sendRequest(options).then(result => {
     return resolve(result);
   }, error => {
     console.log(error);
     return reject('Could not create "Daily News" story.');
   });
 });
}

接下来, createDailyNewsStory 处理程序调用 createDailyNewsStory 函数,该函数通过我们的 API 触发 dailyNews 终端节点,如下所示。

NewsCorpController.php
public function dailyNews()
{
   $show = Show::find(DailyNewsStory::SHOW_ID);
   $storyBuilder = new StoryBuilder($show);

   $dateTime = Carbon::now('Australia/Sydney')->format('F j (g:00 a)');
   $title = $show->title . ' - ' . $dateTime;

   $story = new DailyNewsStory;
   $story->setLimit(10);
   $story->setTitle($title);
   $story->setDescription($title);

   $episode = $storyBuilder->fetch($story)->publish();

   return $this->response->item($episode, new EpisodesTransformer);
}

DailyNewsStory 扩展 StoryBase 类,该类对 NewsCorpApi 类进行依赖关系注入。来自 DailyNewsStory 的值传递到 NewsCorpApi 类,该类用于获取和标准化数据。

接下来,为获取的所有报道生成音频,以单集形式发布。这是通过 StoryBuilder 类实现的,如下所示。

StoryBuilder.php
public function publish()
{
   $title = $this->story->getTitle();
   $description = $this->story->getDescription();

   if (!$episode = $this->episodes->findByTitleAndDescription($title, $description)) {
       $audio = $this->makeAudio();
       $fileName = $this->storage->putContent($audio->content(), Polly::OUTPUT_FORMAT);

       $data = [
           'podcast_id' => $this->show->id,
           'title' => $title,
           'description' => $description,
           'media_file' => $fileName,
           'length' => $this->storage->getSize($fileName),
       ];

       $episode = $this->episodes->create($data);
   }

   return $episode;
}

public function makeAudio()
{
   $polly = new Polly;

   $audioStream = null;
   foreach ($this->story->getBody() as $body) {
       $audioStream .= $polly->makeAudioStream($body);
   }

   return $polly->makeAudioResponse($audioStream);
}

循环执行 $this->story->getBody() 因为它是包含前述所有 10 条报道的数组。这将通过 Amazon Polly 创建持续的音频流。然后音频流以 mp3 文件形式上传到 S3 存储桶,文件名和其余信息保存到数据库并在请求时返回。

我们很多客户生成大量的丰富内容。我们为他们提供由 Amazon Polly 支持的平台,将其内容转换为音频,然后进行发布、分析和商业化。一家新闻出版商计划通过 Whooshkaa 和 Amazon Polly 文本转语音功能提供其食谱库。

Whooshkaa 一直在寻求音频创新方法。我们寻找新的市场和技术为创作者提供最庞大的发布网络。我们发现,传统出版商和 Amazon Polly 能够成功结合。


作者简介

Robert Loewenthal 是 Whooshkaa 的创始人兼 CEO。Whooshkaa 总部位于澳大利亚悉尼市,是一家提供全方位音频点播服务的公司,可帮助创作者和品牌生成、托管、共享、跟踪内容并进行内容货币化。

使用 Amazon Polly 针对 AWS 账户安全事件进行电话呼叫报警

AWS 账户的安全性是重中之重。随时了解您 AWS 账户中与安全相关的所有最新事件非常重要。您可以通过多种方式接收警报,例如通过电子邮件或短信,不过在本博客帖子中,我将向您演示如何使用 Amazon AI 服务 (例如 Amazon Polly) 以及任何基于云的通信平台 (例如 Twilio),在手机上接听语音警报。

Amazon Polly 是一项将文本转换为逼真语音的服务,让您可以构建支持聊天功能的应用程序,从而打造全新类别的具有语音功能的产品。它使用深度学习技术来合成类似于人声的语音。该服务提供了不同语言的各种语音。

对于外出的企业 IT 安全人员,有关 AWS 账户安全事件的电话呼叫警报可以带来极大的帮助。这些安全事件可以根据事件的严重性和优先级进行自定义。严重性和优先级较高的安全事件可以发送到通过电话呼叫报警的系统中。

对于电话呼叫报警,我会使用 Twilio,它提供了 API 功能,例如语音、视频和消息传送。当给定 AWS 账户中发生安全事件时,使用 Twilio 的平台能够以编程方式发布 API 调用,用于进行电话呼叫。Amazon Polly 将此文本警报转换为在电话呼叫上播放的语音消息。

解决方案概述

该解决方案包括两个系统,如以下架构图所示:

  • 事件检测和通知系统
  • 文本到语音转换系统

事件检测和通知系统与文本到语音转换系统彼此分离,这是因为后一个系统对用户定义的任何其他事件检测通用。在此博客帖子中,作为解决方案示例,我重点介绍文本到语音转换系统,并使用来自我之前博客帖子中介绍的事件检测和通知系统

(more…)

Amazon Polly 增加 9 个 AWS 区域、Korean 语音支持和新的印度英语语音

Amazon Polly 是一种可将文本转换为逼真语音的 AWS 服务。今天,我们非常激动地宣布 Amazon Polly 的可用区域又增加了九个,现在 Polly 可用区域的总数已增加到 14 个。我们还非常激动地宣布推出韩语支持,并且我们向文本转语音产品组合中新增了印度英语语音。我们很高兴地推出了新的韩语女声 Seoyeon 和新的印度英语女声 Aditi。

Amazon Polly 现已在以下 14 个 AWS 区域推出,致力于为全球所有客户带来最高稳定性和最低延迟:亚太地区 (孟买)、亚太地区 (首尔)、亚太地区 (新加坡)、亚太地区 (悉尼)、亚太地区 (东京)、加拿大 (中部)、欧洲 (法兰克福)、欧洲 (爱尔兰)、欧洲 (伦敦)、南美洲 (圣保罗)、美国东部 (弗吉尼亚北部)、美国东部 (俄亥俄)、美国西部 (加利福尼亚北部) 和美国西部 (俄勒冈)。

自从 Amazon Polly 在 2016 年 re:Invent 大会上推出后,我们收到的其中一个最常见的要求是提供更多语言支持。在客户请求的众多语言中,韩语是请求频率最高的语言之一。为了响应客户的需求,我们非常高兴地宣布推出第一套韩语语音 Seoyeon。

(more…)

使用新的声道 SSML 功能修改 Amazon Polly 语音的音品

今天,Amazon Polly 团队很高兴地宣布推出一项新的语音合成标记语言 (SSML) 功能,该功能使得开发人员可以修改任意文本到语音转换 (TTS) 声音的音品。这是一项极具吸引力的功能,适合希望在 Amazon Polly 产品组合中自定义现有语音的客户,使得声音更加贴近在其使用案例中所塑造的特定角色。客户在场景中需要使用多个不同的声音时,该功能尤为有用,因为音品功能使得客户可以轻松地从可用的各个 Amazon Polly 语音自定义多个声音形象。

什么是音品?

音品 描述了人们所感受到的音色或音质,这与音高或音量无关。它经常用于音乐中,例如用于区分铜管乐器和弦乐器,或者用于描述中提琴与小提琴的细微差别。音品是一种可用于区分各种乐器的感知属性,即使这些乐器都在以相同的音量演奏相同的调子。与此类似,在具体的语音场景中,音品是一个声音与另一个声音的区别,即使这些声音具有相同的音高 (即其基本频率) 和音量 (振幅)。

每个人的声音都是独一无二的,这是由于多种因素造成的,包括人的生理机能以及发出声音的方式。每个人的声带、声道的大小和形状甚至整个身体的大小和形状,在决定其正常的语音品质方面都起到了重要的作用。有一些方法,例如个人控制舌头的位置、收紧或松弛肌肉或者施加气压,都可以改变语音的音高、音量和音品。经过专业训练的演员可以学习控制这些动作,甚至能够改变自己的声音来模仿他人的声音。

声道与音高

影响到语音音品的一项重要生理特征是声道,这是从声带顶部直到嘴唇边缘的一个空气腔体。有多块肌肉可以用于改变声道腔体的形状,可以让它变长、变短、变宽或变窄。这些改变的效果是导致放大或过滤掉语音。

音高 是一项听觉属性,影响感受到的声音是高还是低。在发出语音的具体过程中,音高由声带振动的频率决定。相比男性,女性通常具有较短的声带,振动频率较高 (每秒约 180 到 200 个周期)。平均而言,男性具有较长的声带,振动更慢 (每秒约 110 个周期)。与此类似,女性的平均声道长度比男性要短 (分别为约 14 厘米与约 17 厘米)。

声带长度和声道长度具有内在的关联,也就是说,其中一个更长,另一个也倾向于随之更长。利用音品功能,开发人员可以在保留控制音高能力的同时更改声道的大小。

声道和语音合成

使用 vocal-tract-length SSML 标记,您可以通过更改发言者的声道来控制输入语音的音品。这听上去像是更改了发言者的身体大小。当您增加 vocal-tract-length 时,发言者的声音听上去像是他们的个子更大。减小时,听上去像是个子更小。此标记可用于 Amazon Polly 文本到语音转换产品组合中的任何语音。

下面说明了如何修改发言者声道的长度:

  • +n% 或 -n%:按当前语音的相对百分比进行更改,来调整声道长度。例如,+4% 或 -2%。
  • n%:按当前语音的绝对百分比值来调整声道长度。例如,104% 或 98%。
  • 声道长度最多可以增加 100% 和减少 50%。
  • 要将声道长度重置为当前语音的默认值,请使用 <amazon:effect vocal-tract-length=“100%”>

下面的示例说明如何修改声道长度,使用的是 Joanna 的语音:

<speak>
This is my original voice, without any modifications. <amazon:effect vocal-tract-length="+15%"> Now, imagine that I am much bigger. </amazon:effect> <amazon:effect vocal-tract-length="-15%"> 
Or, perhaps you prefer my voice when I'm very small? </amazon:effect> You can also control the 
timbre of my voice by making more minor adjustments. <amazon:effect vocal-tract-length="+10%"> For example, by making me sound just a little bigger. </amazon:effect> <amazon:effect vocal-tract-length="-10%"> Or instead, making me sound only somewhat smaller. </amazon:effect> 
</speak> 
立即收听

语音由 Amazon Polly 提供

(more…)