QPython使用SL4A实现分贝仪

cooolr 于 2022-10-07 发布

需要授权QPython录音录像权限

# 录音并保存到指定的路径
recorderStartMicrophone(targetpath:str)

# 停止录音
recorderStop()

因为sl4a api录音文件是mp4格式,需要使用moviepy库提取wav音频,

而moviepy又依赖ffmpeg,需要在termux安装后提取移植到qpython,

from moviepy.editor import AudioFileClip

my_audio_clip = AudioFileClip("my_video.mp4")
my_audio_clip.write_audiofile("my_audio.wav")

计算分贝值需要转换wav为pcm格式

import numpy as np
def wav2pcm(wavfile, pcmfile, data_type=np.int16):
    f = open(wavfile, "rb")
    f.seek(0)
    f.read(44)
    data = np.fromfile(f, dtype= data_type)
    data.tofile(pcmfile)
import array
import numpy as np
import os
from math import log, exp
 
pcm_path = 'test_audio.pcm'#改
def readPCM(fileName):
    file = open(fileName, 'rb')
    pcm_data = array.array('h')
    size = int(os.path.getsize(fileName) / pcm_data.itemsize)
    pcm_data.fromfile(file, size)
    file.close()
    return np.array(pcm_data)#/ 32768
 
data = readPCM(pcm_path)
sum_ = 0
for k in range(len(data)):
	sum_+= abs(data[k])
sum_ = sum_/len(data)
print(len(data),max(data),min(data),sum(data>=0),len(data),data.shape)
 
fenbei = 20*log(max(data)/65535,10)
fenbei = 20*log(sum_,10)
print('fenbei = ',fenbei)

完整代码

# -*- coding: utf-8 -*-

import os
import time
import array
import pymysql
import numpy as np
from math import log, exp
from androidhelper import Android
from moviepy.editor import AudioFileClip

mp4_file_name = "/sdcard/noise.mp4"
wav_file_name = "/sdcard/noise.wav"
pcm_file_name = "/sdcard/noise.pcm"

droid = Android()
db = pymysql.connect(host='192.168.10.12', port=3306, user='root', password='123456', db='data_collect', charset='utf8', autocommit=True)
cursor = db.cursor()

def recorder():
    droid.recorderStartMicrophone(mp4_file_name)
    time.sleep(5)
    droid.recorderStop()

def translate_wav():
    audio_clip = AudioFileClip(mp4_file_name)
    audio_clip.write_audiofile(wav_file_name)

def translate_pcm():
    f = open(wav_file_name, "rb")
    f.seek(0)
    f.read(44)
    data = np.fromfile(f, dtype=np.int16)
    data.tofile(pcm_file_name)
    f.close()

def readPCM():
    f = open(pcm_file_name, 'rb')
    pcm_data = array.array('h')
    size = int(os.path.getsize(pcm_file_name) / pcm_data.itemsize)
    pcm_data.fromfile(f, size)
    f.close()
    return np.array(pcm_data)

def getdB():
    data = readPCM()
    sum_ = 0
    for k in range(len(data)):
          sum_+= abs(data[k])
    sum_ = sum_/len(data)
 
    dB1 = 20*log(max(data)/65535,10)
    dB2 = 20*log(sum_,10)
    print(f'{time.ctime()[11:19]} - 分贝 = ',dB1, dB2)
    return dB2

def savedB(dB):
    db.ping(True)
    sql = f'insert into noise_data(value) values({dB})'
    sql2 = 'delete from noise_data where create_time<(current_timestamp - interval 1 day)'
    cursor.execute(sql)
    cursor.execute(sql2)

def main():
    recorder()
    translate_wav()
    translate_pcm()
    dB = getdB()
    savedB(dB)

if __name__ == "__main__":
    while True:
        try:
            main()
        except:
            try:os.remove(mp4_file_name)
            except:pass
            try:os.remove(wav_file_name)
            except:pass
            try:os.remove(pcm_file_name)
            except:pass
        time.sleep(5)

数据保存到mysql后,结合metabase展示效果如图

01.jpg