はじめに
上記記事の続きになります。
前回はPyAudioを使ってチャイム音を取得し、取得した音声データをFFTして特徴を出しました。
今回はFFT後の値が閾値を超えたときに、LINEに通知を送る実装を行ったので記事を書きます。
LINEへの通知方法
LINE Notifyを使用します。
使い方は簡単で、まず通知先を設定して、アクセストークンを発行します。
アクセストークンとメッセージ内容を付与して、URLにリクエストすると設定した通知先にメッセージが送信されます。
実装
前回のプログラムを元に処理を追加しました。
.py
import numpy as np
import requests
import pyaudio
import matplotlib.pyplot as plt
from scipy.fftpack import fft
# 設定値
FORMAT = pyaudio.paInt16
CHANNELS = 1 # マイクのチャンネル数
RATE = 48000 # マイクのサンプリングレート
CHUNK = 1024
IDINDEX = 23 # マイクのindex
DATA_LENGTH = 1000 # 格納するデータ数
# メイン処理
def main():
# 変数
y = []
# マイクの設定
audio = pyaudio.PyAudio()
stream = audio.open(
format = FORMAT
,channels = CHANNELS
,rate = RATE
,frames_per_buffer=CHUNK
,input=True
,output=False
)
while stream.is_active():
try:
# 音声データの取得
input = stream.read(CHUNK, exception_on_overflow=False)
ndarray = np.frombuffer(input, dtype='int16')
for i in ndarray:
data = i.item() # 音声データの取得
append_arr(y, data, DATA_LENGTH) # 音声データを配列に格納
# FFT
freq = np.linspace(0, RATE, DATA_LENGTH)
yf = np.abs(fft(y))
yf = yf * yf
# 判定(1000Hzの値が閾値を超えた場合通知する)
if len(yf) == DATA_LENGTH:
if yf[22] > 100000000000:
send_line_notify('チャイムがなったぞ!')
except KeyboardInterrupt:
break
# plt.plot(freq[0:int(DATA_LENGTH/2)], yf[0:int(DATA_LENGTH/2)])
# plt.show()
stream.stop_stream()
stream.close()
stream.terminate()
# 配列へのデータ追加(配列数がlengthを超えた場合古いデータを削除)
def append_arr(arr, data, length):
arr.append(data)
while len(arr)>length:
arr.pop(0)
# ラインに通知
def send_line_notify(notification_message):
line_notify_token = '{LINE Notifyのアクセストークン}'
line_notify_api = 'https://notify-api.line.me/api/notify'
headers = {'Authorization': f'Bearer {line_notify_token}'}
data = {'message': f'message: {notification_message}'}
requests.post(line_notify_api, headers = headers, data = data)
if __name__ == "__main__":
main()
上記プログラムは、1000Hz音声を取得したときLINEに通知を送る仕組みになっています。
閾値を修正することで他の特徴を持つ音声も検知することができます。
※連続でLINE通知されるなど修正すべきところがいくつかありますので、ご注意ください
さいごに
LINE Notifyが予想以上に使いやすかったです。
通知部分のみであれば10分くらいで実装できます。
システム監視等の通知にも使えるかもですね!