つよくなるブログ

その場にとどまるためには、全力で走り続けなければならない

Google Cloud Speech-to-Text 向けに.wav の音声をステレオからモノラルに変換する

Google Cloud Speech-to-Text (以下、Speech-to-Text)で音声(.wav)から文字起こしをした時にMust use single channel (mono) audio, but WAV header indicates 2 channels.エラーが発生したので対策についてまとめました。

前提

  • 1 人が喋っている動画の文字起こしをしたい
  • ↑ の動画から音声のみを抜き出した.wav を使用する

Speech-to-Text の複数チャンネルの扱いについて

Speech-to-Text には複数のチャンネルを含む音声を扱えるオプションが存在しています。
電話やポッドキャストなどの複数人の会話を、発話者を認識して誰が話した音声か特定して文字起こしができます。

cloud.google.com

ですが、今回やりたいのは 1 人で話している音声の文字起こしです。
その場合の音声(.wav)は single channel(モノラル) を使用しなさい、というのが冒頭のエラー内容です。

.wav のチャンネルついて

モノラルは 1(0x0100)、ステレオは 2(0x0200)

www.youfit.co.jp

ステレオからモノラルへの変換

ffmpeg と Python の2種類の方法で紹介します。

状態確認

ffmpeg

-i: 入力ファイルのパス
-hide_banner: ビルドオプション、バージョン情報などを非表示にする

$ ffmpeg -i audio-stereo.wav -hide_banner
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from 'audio-stereo.wav':

...省略...

Python

import wave

wave_read = wave.open('audio-stereo.wav', "rb")
print ("Channel:", wave_read.getnchannels())

# output: Channel: 2

変換

ffmpeg

-ac: チャンネル数

$ ffmpeg -i audio-stereo.wav -hide_banner -ac 1 audio-mono.wav

Python

Python での変換には pydub を使用します。 pydub は ffmpeg に依存しているので、インストールしておく必要があります。

github.com

$ pip install pydub
from pydub import AudioSegment

audio = AudioSegment.from_wav("audio-stereo.wav")
audio = audio.set_channels(1)
audio.export("audio-mono.wav", format="wav")

再度確認

ffmpeg

$ ffmpeg -i audio-mono.wav -hide_banner
Guessed Channel Layout for Input Stream #0.0 : mono
Input #0, wav, from 'audio-mono.wav':

...省略...

Python

from pydub import AudioSegment

audio = AudioSegment.from_wav("audio-mono.wav")
audio = audio.set_channels(1)
audio.export("audio-mono.wav", format="wav")

# output: Channel: 1

まとめ

.wav のチャンネル変換方法を Python と ffmpeg の 2 種類の方法で紹介しました。

Speech-to-Text の拡張モデルで日本が使えるようになって欲しい!

cloud.google.com

Monthly LINE API Update 2020-12

f:id:morugu:20210104120836p:plain

2020年 12 月の LINE API 関連のまとめです。

シェアターゲットピッカーの UI 改善

developers.line.biz

  • シェアターゲットピッカー = LIFF から起動して LINE の友だちにメッセージを送信する機能です
  • デフォルトでトークのセクションが開き最近やり取りした友だちが優先して表示されるようになったため、送信先を見つけやすくなりました

LIFF v2.6.0 リリース

developers.line.biz

  • 内部挙動の変更のみで追加機能などはなし

Webhook イベントオブジェクトに新しいプロパティが追加

developers.line.biz

  • スタンプが送信されたときに「どんな気持ちを表現しているスタンプか」を把握するためのプロパティ(webhookObj.events.message.keywords)が追加
  • スタンプにはキーワードが設定されており、最大 15 個のキーワード配列で返される
  • 16 個以上のキーワードを持つスタンプはランダムに 15 個のキーワード配列で返される

LIFF ブラウザの iOS サポートバージョンが変更

developers.line.biz

  • iOS 12.0 以降をサポート対象に変更(変更前は iOS 11 以降)

その他

iOS の LIFF で getUserMedia が使えるように

iOS での LIFF は WKWebView が使われており、getUserMedia が未対応だったため WebRTC を使った映像共有などができませんでした。

検証記事:

qiita.com

iOS 14.3 から WKWebView で getUserMedia が使えるようになった(Android では以前から使えていた)ので、 LIFF 上で WebRTC を使ったアプリの開発が可能になりました。

とはいえ、最新の iOS でないと動作しないため回避策が必要になります。

回避策について:

www.line-community.me

LINE API Use Case が公開

developers.line.biz

  • LINE API の活用事例が紹介されたサイト
  • 「LINE で予約」「自治体での防災、粗大ごみ収集」など様々な LINE を使った事例が掲載されていて、これからら LINE を使って何かやりたい方にオススメです
  • 開発者としても LINE API の事例として参考になる使い方が多く載っています

「福岡市 LINE 公式アカウント 防災ハンドブック」の配布開始

linefukuoka.co.jp

  • LINE 公式アカウントの使い方のを説明したハンドブック
  • 実際のハンドブックはここから読めます
  • LINE が慣れ親しんだアプリとはいえ、防災目的で使うのであれば本当に"誰でも"使えるようにするためこういったアプローチも必要になってきますね

ドキュメントの更新

  • LINE Developers サイトの「ガイド」の名称を「ドキュメント」へ変更

developers.line.biz

  • LINE Developers コンソールへログインするアカウントごとに利用できる機能の一覧を追加しました

developers.line.biz

  • LINE Pay の開発者向けドキュメントが LINE Developers サイトに公開されました

developers.line.biz

今まで独自のページで存在していた LINE Pay が LINE Developers に統合されました。

まとめ

LIFF から WebRTC を使ったアプリを開発が iOS でも可能になったことで
まずはLINE ボットに問い合わせ -> 必要に応じてビデオ通話でオンライン相談窓口対応のようなサービスが実現できそうです!

以上、2020 年 12 月のアップデートでした!

ドングリ FM の 2020 年 をデータとともに振り返る

この記事は「ドングリ FM リスナーの Advent Calendar 2020」の 14 日目の記事です。

adventar.org


ドングリ FMとは

「つまらなくておもしろい、いつも聴いてるのに内容は覚えていない」

で有名な narumi さんとなつめぐさんの 2 人が話すポッドキャスト番組です。

現在(2020 年 12 月 14 日)のエピソード数は 660 回 を超えて 700 回へ向かっています。

そして今年の 1 月に

ドングリ FM の過去回を検索できるサイトドングリ FM 検索」をつくりました!

dongurifm-search.netlify.app

つくった背景

第 493 回 でドングリ FM の過去のエピソードを探すときに
ひたすら SoundCloud をスクロールしてさかのぼっている」と聞き
その時間を使ってこの楽しいポッドキャストを 1 エピソードでも配信を増やしてほしい...!
と思ったのがきっかけでした。

soundcloud.com

お二人の SoundCloud ひたすらスクロールを解決するために作ったサービスでしたが

多くのドングリ FM リスナーの方にも使ってもらえています!

第 513 回の放送と note でも紹介されました!

soundcloud.com

donguri.fm

データで振り返る 2020 年のドングリ FM

そんなドングリ FM 検索を運用しているので

世界一ドングリ FM のデータを持っていると言っても過言ではないと思い

以下、そのデータを活用して 2020 年のドングリ FM を振り返ってみようのコーナーです!

2020 年の最初に公開されたエピソードは?

494 令和2年になってしまいました

お正月の BGM & 米津玄師のレモンから始まったおめでたい回です。

soundcloud.com

2020 年に公開されたエピソード数は?

現在(2020 年 12 月 14 日)の最新が第 660 回なので

2020 年に公開されたエピソード数は 166!

ざっくり 2 日 に 1 エピソードのペースで公開されています。

2020 年で長編(時間が長かった)エピソード Top 3

年末年始に聞き返したい長編エピソード!

1 位: 592 カツセマサヒコさんをゲストに創作と青春を語る

1 時間 17 分 23 秒

soundcloud.com

2 位: 572 朽木誠一郎さんをゲストにメディアとダイエットを語る

1 時間 13 分 15 秒

soundcloud.com

3 位: 526 ラジオ番組「たのしいラジオ・ドングリ FM」

1 時間 6 分 44 秒

soundcloud.com

2020 年で短編(時間が短かかった)エピソード Top 3

まだドングリ FM を聴いたことない方にオススメな短編エピソード!

1 位: 619 Google Pixel Buds とかいう翻訳イヤホンがすごいらしい

5 分 29 秒

soundcloud.com

2 位: 646 猥談バーに行きたい

6 分 11 秒

soundcloud.com

3 位: 620 「サマータイムレンダ」とマイナースポーツ漫画が面白い

6 分 16 秒

soundcloud.com

2020 年 のドングリ FM 頻出単語 Top 5

2020 年に公開された全てのエピソードのタイトルから単語を抽出して意味がわかるもので選出しました。

1 位: 語る

2 位: ドングリ

3 位: 面白い

4 位: おすすめ, 最強, Zoom, ポッドキャスト, ラジオ

5 位: 収録, 退職, 公開

AI にタイトルを付けさせたとすると
「面白いポッドキャストを語る」
「最強の退職ブログを公開」
のようなタイトルが生まれてきそうです。

おまけ

626 ビッグデータを少しぶっ壊したいで語られていた、壮大な目標 1000 万エピソードまで

このペースだと 60606 年、平均 80 歳とすると 757 世代後に達成されます、大変なことだなあ。

Amazon Alexa の日本語エンジンが壊れるその日まで、ドングリ FM を聞き続けていきます。


この記事は「ドングリ FM リスナーの Advent Calendar 2020」の 14 日目の記事でした。

明日はもこ 🐈tomoko miura さんです。お楽しみに!

Monthly LINE API Update 2020-11

先日開催された LINE DEV DAY 2020 のセッションで
約 60 万アカウントのチャットボットが作成されLINE 上で動いていていると発表されていました。

logmi.jp

多くの開発者に使われている LINE API の情報は

LINE DevelopersLINE Developers Community にありますが

日々のアップデートに伴う新機能の解説・ユースケースなどの情報はまだまだ少ないと感じています。

そういった情報を月 1 回まとめて紹介してきます。

2020 年 11 月のアップデート

11 月は 4 件のアップデートがありました。

Social API が LINE ログインの一部になりました

2021 年 3 月 1 日に LIFF アプリおよび LINE ミニアプリのパーマネントリンクのリダイレクト設定から「置換(後方互換性モード)」が廃止されます

  • 「LIFF URL の追加情報の処理方法」の「置換(後方互換性モード)」が非推奨になった後に廃止されて「連携」のみになります
  • LIFF SDK v2.3.0 から「連結」をサポートしているため、それ以前のバージョンを使っている場合はアップデートが必要になります
  • スケジュール
    • 2021 年 1 月 11 日に 「置換(後方互換性モード)」の利用は非推奨に、2021 年 3 月 1 日に「置換(後方互換性モード)」が廃止、連携に切り替えが行われます
  • 「連結」一択になると設定不要なので LIFF の設定項目から消える?

2020 年末にビーコンイベントの leave イベントを廃止します

  • ビーコンイベントの leave の廃止が予定されており、代わりに stay の利用が推奨されています
  • スケジュール
    • 2020 年末に廃止、2021 年 1 月上旬に Webhook の送信が停止されます
      • 2020 年末 = 2020 年 12 月 31 日?

2020 年 12 月より Messaging API のレート制限が変更されます

まとめ

Messaging API レート制限の変更は制限緩和のアップデートなので LINE 公式アカウントをチャットボットとしてヘビーに使っている開発者にとっては良いアップデートですね。

以上、2020 年 11 月の LINE API アップデートでした!

Serverless の TypeScript テンプレートを使って Lambda 関数をデプロイする

Lambda をはじめサーバーレスアプリケーションの管理ができる Serverless Framework
TypeScript を使ってデプロイして動作確認まで試してみました。

TypeScript テンプレートを使うと関数を TypeScript で書けるのはもちろん、
YAML で書いていた構成設定ファイルも TypeScript で書けるのは大きなメリットです!

www.serverless.com

Node.js のバージョン確認

$ node -v
v12.18.4

Serverless をインストール

$ npm install -g serverless

serverless もしくは省略した sls でコマンドが使えるようになるので、バージョンを確認します。

$ sls --version
Framework Core: 2.8.0
Plugin: 4.1.1
SDK: 2.3.2
Components: 3.2.7

それぞれなんのバージョンなのか?

Framework Core: Serverless 本体のバージョン

Plugin: @serverless/enterprise-plugin のバージョン

Serverless のエンタープライズ版を使う時に有効にするプラグインです。
エンタープライズ版は Serverless を使ってデプロイしたアプリケーションの監視・テストなどができるサービスです。

SDK: @serverless/platform-sdk のバージョン

各プラットフォーム(AWS, GCP など)とのインターフェースとなる SDKです。
今後は廃止予定(今後はバグ修正のみ)の SDKで@serverless/platform-clientへ統合される予定です。

Components: @serverless/components のバージョン

sls --version コマンドの実装箇所はこちら

github.com

Serverless プロジェクトの作成

sls create コマンドを使ってプロジェクトを作成します。

-t にはテンプレート名を指定します。今回は AWS Lambda の TypeScript テンプレートを使うので aws-nodejs-typescriptを指定します。

-p にはプロジェクト名を指定します。

$ sls create -t aws-nodejs-typescript -p example-project

Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/path/example-project"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v2.8.0
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs-typescript"

プロジェクトの作成が完了したら、必要なパッケージをインストールします。

$ cd example-project

$ npm install

つづいて生成されたファイルを確認します。

$ ls | xargs basename

handler.ts
package.json
serverless.ts
tsconfig.json
webpack.config.js

serverless.ts の確認

注目箇所はproviderfunctionsの 2 点です。

providerには「利用するサービスは AWS で Node.js v12 を使う」

functions には「handler.ts の hello 関数を hello という名称の Lambda 関数として使い、API Gateway 経由で /hello に GET リクエストでアクセスできるようにする」

といった内容が書かれています。

TypeScript で書くことで必須項目の有無、型による制限などの恩恵が受けられます。

import type { Serverless } from 'serverless/aws';

const serverlessConfiguration: Serverless = {
  service: {
    name: 'example-project',
    // app and org for use with dashboard.serverless.com
    // app: your-app-name,
    // org: your-org-name,
  },
  frameworkVersion: '2',
  custom: {
    webpack: {
      webpackConfig: './webpack.config.js',
      includeModules: true,
    },
  },
  // Add the serverless-webpack plugin
  plugins: ['serverless-webpack'],
  provider: {
    name: 'aws',
    runtime: 'nodejs12.x',
    apiGateway: {
      minimumCompressionSize: 1024,
    },
    environment: {
      AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
    },
  },
  functions: {
    hello: {
      handler: 'handler.hello',
      events: [
        {
          http: {
            method: 'get',
            path: 'hello',
          },
        },
      ],
    },
  },
};

module.exports = serverlessConfiguration;

handler.ts の確認

hello 関数が生成され デフォルト では APIGatewayProxyHandler が指定されており、
API Gateway + Lambda の構成を前提としたコードが生成されます。

S3 からのイベントを受け取る関数の場合は S3Handler
DynamoDB からのイベントを受け取る関数の場合は DynamoDBStreamHandler など
関数の目的に合わせた型を指定することで event オブジェクトで型情報が使えるようになります。

import { APIGatewayProxyHandler } from 'aws-lambda';
import 'source-map-support/register';

export const hello: APIGatewayProxyHandler = async (event, _context) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Go Serverless Webpack (Typescript) v1.0! Your function executed successfully!',
        input: event,
      },
      null,
      2
    ),
  };
};

ローカル環境で動作確認

sls invoke コマンドを使って、ローカル環境で関数を実行して動作確認をします。

sls invoke local でローカル環境で関数を実行できます。

-f には実行対象の関数名を指定します。

$ sls invoke local -f hello

Serverless: Bundling with Webpack...
Time: 153ms
Built at: 2020-10-23 22:32:09
     Asset      Size   Chunks             Chunk Names
handler.js  6.29 KiB  handler  [emitted]  handler
Entrypoint handler = handler.js
[./handler.ts] 316 bytes {handler} [built]
[source-map-support/register] external "source-map-support/register" 42 bytes {handler} [built]
{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Go Serverless Webpack (Typescript) v1.0! Your function executed successfully!\",\n  \"input\": \"\"\n}"
}

AWS にデプロイ

sls deploy コマンドを使って関数を AWS にデプロイします。

$ sls deploy

~~~~~ 省略 ~~~~~
Serverless: Stack create finished...
Service Information
service: example-project
stage: dev
region: ap-northeast-1
stack: example-project-dev
resources: 8
api keys:
  None
endpoints:
  GET - https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello
functions:
  hello: example-project-dev-hello
layers:
  None

Serverless: Stack update finished... が表示されたらデプロイ完了です!

デプロイされた関数の動作確認

sls invokelocal を付けないと AWS にデプロイされた関数が実行されます。

$ sls invoke -f hello

{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Go Serverless Webpack (Typescript) v1.0! Your function executed successfully!\",\n  \"input\": {}\n}"
}

デプロイログの endpoints に表示されている URL でアクセス可能です。

$ curl -X GET https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/hello

{
  "message": "Go Serverless Webpack (Typescript) v1.0! Your function executed successfully!",
  "input": {
    ~~~~~ 省略 ~~~~~
  }
}

以上で、Serverless Framework で TypeScript テンプレートを使った Lambda 関数のデプロイは完了です!

おまけ

他に使えるテンプレートは?

Serverless Framework で使えるテンプレートこちらです。

serverless/lib/plugins/create/templates at master · serverless/serverless · GitHub

GCP や Azure のテンプレートもあります。

TypeScript の型定義はどこにあるの?

Serverless Framework の本体には型定義は入っておらず、TypeScript の型定義は @type/serverless に存在しています。

www.npmjs.com

ほとんどの型が網羅されていますが、用途として少ない型はないことも。
必要であればコントリビュートして追加することが可能です。