Une fête populaire sur le Web, Python détecte un état silencieux et joue une voix.

Préface

Boire Web qui est populaire parce que le monde est le monde.

Cependant, après un certain nombre de réunions, il y aura toujours un moment où personne ne prend la parole. En premier lieu, tout le monde reste à la maison tout le temps, donc on n'en parle pas beaucoup. Je suis sûr que certaines personnes pensent qu'elles ne devraient pas participer à une telle fête, mais c'est difficile car il n'y a aucune raison de refuser cela.

01.png

Peu importe à quel point vous êtes proche, la soirée buvant sera silencieuse lorsqu'il n'y aura plus de contenu à parler.

La soirée en elle-même se poursuivra paresseusement, donc si vous vous sentez mal à l'aise, ne vous inquiétez pas. Une telle situation est la pire pour quelque raison que ce soit.

Par conséquent, cette fois, afin d'éviter l'état silencieux ** (état maladroit dû à) ** dans la partie buvant le Web, je voudrais créer un programme en Python qui détecte l'état silencieux et joue une voix. (C'est un soulagement)

Cible

J'utilise généralement Zoom pour les réunions telles que les réunions Web, donc je vise à l'utiliser avec ** Zoom **.

Cependant, en réalité, le son de l'ensemble du système sera surveillé, de sorte que tout logiciel devrait probablement être en mesure de le gérer.

Le but est de surveiller l'entrée audio de Zoom pendant 10 secondes, et s'il détermine qu'il n'y a pas d'entrée = pas de son, le fichier musical sera lu au hasard à partir du dossier spécifié.

environnement

J'ai commencé avec une idée, donc j'utilise ** Python ** comme langage de programmation, mais cela ne veut rien dire. L'environnement d'exploitation est le suivant.

■Windows10 ■Python3.7

Les bibliothèques utilisées sont les suivantes.


import pyaudio
import numpy as np
import wave
import math

from mutagen.mp3 import MP3 as mp3
import pygame
import time

import glob
import random
import sys

Personnellement, je voulais utiliser Zoom avec la meilleure qualité sonore possible, j'ai donc une interface audio et un microphone séparés (le son est probablement un peu coupé du côté Zoom, donc cela n'a pas beaucoup de sens, je suis autonome) ..

03.jpg

■marantz / AUDIO SCOPE SG-5BC ■CREATIVE / SB X-Fi Surround 5.1

Maintenant écrivons le programme.

Code source

audio = pyaudio.PyAudio()

def system(FORMAT, CHANNELS, RATE, CHUNK):

    stream = audio.open(format=FORMAT,
                        channels=CHANNELS,
                        rate=RATE,
                        input=True,
                        output=True,
                        input_device_index=1,#← Veuillez changer pour un index approprié.
                        output_device_index=7,#← Veuillez changer pour un index approprié.
                        frames_per_buffer=CHUNK)

    return stream

Tout d'abord, nous instancions et utilisons pyaudio.PyAudio () pour contrôler l'entrée audio par le microphone.

La voix d'entrée à surveiller est spécifiée à partir de la valeur numérique de ʻinput_device_index`. Si vous ne connaissez pas la valeur de l'index de l'appareil, vous pouvez le rechercher avec le code suivant.

for index in range(0, p.get_device_count()):
    print(p. get_device_info_by_index(index))

En prenant mon environnement comme exemple, le résultat est le suivant.

{'index': 0, 'structVersion': 2, 'name': 'Microsoft Sound Mapper- Input', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 1, 'structVersion': 2, 'name': 'Redirection de lecture(SB X-Fi Surround 5.1)', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 2, 'structVersion': 2, 'name': 'ligne(USB2.0 High-Speed True HD ', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 3, 'structVersion': 2, 'name': 'ligne/Entrée microphone(SB X-Fi Surround 5.1', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 4, 'structVersion': 2, 'name': 'SPDIF In (USB2.0 High-Speed Tru', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 5, 'structVersion': 2, 'name': 'Microphone(USB2.0 High-Speed True HD ', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 6, 'structVersion': 2, 'name': 'Microsoft Sound Mapper- Output', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 2, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 7, 'structVersion': 2, 'name': 'orateur(SB X-Fi Surround 5.1)', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 6, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 8, 'structVersion': 2, 'name': 'Sortie SPDIF(SB X-Fi Surround 5.1)', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 6, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 9, 'structVersion': 2, 'name': 'SPDIF Out (USB2.0 High-Speed Tr', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 2, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}
{'index': 10, 'structVersion': 2, 'name': 'orateur(USB2.0 High-Speed True H', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 8, 'defaultLowInputLatency': 0.09, 'defaultLowOutputLatency': 0.09, 'defaultHighInputLatency': 0.18, 'defaultHighOutputLatency': 0.18, 'defaultSampleRate': 44100.0}

Dans mon environnement, il y a plusieurs interfaces audio connectées, donc il y a beaucoup d'index comme celui-ci.

Cette fois, il est nécessaire de lire non seulement la voix d'entrée mais aussi l'état de la conversation de l'autre partie et l'état de l'écran partagé avec Zoom.

Par conséquent, dans ce cas, l'index utilisé est la redirection de lecture, 1 pour surveiller l'ensemble du système. Vérifiez vous-même cette valeur et remplacez-la par une valeur appropriée.

Il y a un élément qui spécifie ʻoutput_device_index, mais ceci est spécifié parce que vous voulez lire un fichier audio au format wav. Cet élément n'est pas nécessaire surtout si vous ne prévoyez pas de lire le fichier wav. En premier lieu, il est volontairement transformé en fonction, donc si vous n'avez pas de plan, vous pouvez spécifier FORMAT, CHANNELS, RATE, CHUNK` sans en faire une fonction.

frames = []

def surveillance():

    print("Under surveillance...")

    FORMAT = pyaudio.paInt16
    CHANNELS = 1  #monaural
    RATE = 44100  #Taux d'échantillonnage
    CHUNK = 2 ** 11  #Score des données
    RECORD_SECONDS = 10  #Durée d'enregistrement

    stream = system(FORMAT, CHANNELS, RATE, CHUNK)

    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        buf = stream.read(CHUNK)
        data = np.frombuffer(buf, dtype="int16")
        frames.append(max(data))

    stream.stop_stream()

    calculation()

Le nom de la fonction est "moniteur".

Ici, la voix est entrée dans python pendant 10 secondes, et la ** valeur maximale ** de la forme d'onde de la voix à chaque seconde est extraite et ajoutée aux frames.

Pour expliquer un peu, dans ce cas, RATE = 44100, donc la fréquence d'échantillonnage est de 44,1 kHz. Cela signifie que nous obtenons 44100 niveaux de volume par seconde. Un son est une onde, et tant qu'il s'agit d'une onde, les valeurs négatives sont naturellement incluses. Si vous voulez vérifier le niveau exact toutes les 1 / 44,1 secondes, vous devez obtenir la valeur absolue, mais cette fois seule la valeur maximale est enregistrée car il suffit de juger s'il y a un son dans les 10 secondes.

La valeur acquise est convertie en 2 ** 16 pas avec une plage dynamique de 16 bits par «np.frombuffer». Cependant, comme mentionné précédemment, il a des valeurs positives et négatives, la valeur maximale est donc 32767.

def calculation():

    print("Calculation")

    rms = (max(frames))

    db = 20 * math.log10(rms) if rms > 0.0 else -math.inf
    print(f"RMS:{format(db, '3.1f')}[dB]")

    if (db<=65):#← Veuillez ajuster le nombre en fonction de l'environnement
        random_music()
        #disc_jockey()

    else:
        pass

    frames.clear()

Vient ensuite la fonction qui détermine l'état silencieux.

Enregistrez les valeurs acquises pour faciliter la compréhension des changements de niveau. Déterminez le seuil et branchez à «si». Dans mon environnement, environ 65 dB semble être une bonne valeur. Modifiez cette valeur en fonction de votre propre environnement.

def random_music():

    print("Random music")

    files = [r.split('/')[-1] for r in glob.glob('./data/*.mp3')]
    filename = random.choice(files)  #Le fichier mp3 que vous souhaitez lire
    print(filename)

    pygame.mixer.init()
    pygame.mixer.music.load(filename)  #Charger la source sonore
    mp3_length = mp3(filename).info.length  #Obtenez la longueur de la source sonore
    pygame.mixer.music.play(1)  #La lecture démarre. Jouez n fois si la partie 1 est modifiée(Dans ce cas, xn également le nombre de secondes sur la ligne suivante.)
    time.sleep(mp3_length + 0.25)  #Après avoir démarré la lecture, attendez la longueur de la source sonore(0.Attendre 25 est l'élimination des erreurs)
    pygame.mixer.music.stop()  #La lecture s'arrête après avoir attendu la durée de la source sonore

Enfin, c'est un programme qui extrait aléatoirement les fichiers mp3 de dossiers arbitraires et les lit. Dans mon cas, je le mets dans data directement sous le répertoire du code source.

try:
    while True:
        surveillance()

except KeyboardInterrupt:
    print("Emergency stop")
    sys.exit(0)

stream.close()
audio.terminate()

Après cela, le programme est mis en boucle et surveillé.

Lorsque le silence est interrompu de toute urgence, il se termine par ctrl + c.

def disc_jockey():

    print("Play...")

    filename = "./disc_jockey.wav"
    wf = wave.open(filename, "rb")

    FORMAT = audio.get_format_from_width(wf.getsampwidth())
    CHANNELS = wf.getnchannels()
    RATE = wf.getframerate()
    CHUNK = wf.getnframes()

    stream = system(FORMAT, CHANNELS, RATE, CHUNK)

    data = wf.readframes(CHUNK)
    stream.write(data)

    stream.start_stream()
    stream.stop_stream()
    stream.close()

    random_music()

Au fait, j'ai mentionné au début que je voulais aussi jouer à wav, donc je vais décrire comment le faire.

C'est fondamentalement la même que la méthode d'enregistrement, mais dans ce cas, il est nécessaire de déterminer la valeur en fonction de l'état du fichier, de sorte que chaque valeur est acquise par "wave" et remplacée.

La raison pour laquelle le nom de la fonction est DJ est que ** même si la musique joue soudainement, l'autre partie n'est pas claire. ** Je l'ai créée ici avec l'intention d'insérer une voix d'introduction de chanson.

Et les données que j'avais étaient "Allons à la chanson ici" de ** Chris 〇Puller ** et le fichier de voix wav de ** Ioin Hikaru **. Maintenant ça.

02.png

... je ne sais pas pourquoi.

Résumé

Je ne pouvais pas sortir à cause d'un certain virus, et la soirée silencieuse sur le Web est toujours en cours, mais faisons tous de notre mieux.

Recommended Posts

Une fête populaire sur le Web, Python détecte un état silencieux et joue une voix.
Créer une carte Web en utilisant Python et GDAL
Lancer un serveur Web avec Python et Flask
Obtenez la page Web Python, encodez et affichez les caractères
Créer une application Web pour la transcription vocale
[Python] renvoie A [ou / et] B
Jetons JavaScript et écrivons un front-end Web en Python!
Je souhaite créer une application Web en utilisant React et Python flask