This commit is contained in:
Doug Le Tough 2019-08-26 22:21:55 +11:00
parent eb91e1f684
commit a0416f3661
3 changed files with 115 additions and 56 deletions

View File

@ -6,20 +6,41 @@ LogStreamer est un logiciel permettant la diffusion sonore d'un fichier via un s
## Prérequis ## Prérequis
* python3 * python3
* pigtail * oggenc
```
pip3 install pigtail
```
## Utilisation ## Utilisation
* Ajuster les valeurs des constantes LOG et WAV_OUTPUT en fonction des besoins ```
* LOG: Le log à jouer logstreamer.py -h
* WAV_OUTPUT: Le fichier wav de sortie
* MAX_DURATION: La durée maximale d'une note usage: logstreamer.py [-h] --log LOG [--workdir WORKDIR] [--duration DURATION]
* EXCLUDE: Les caractères dont les valeurs sont ajoutées à cette liste ne seront pas traités [--amplitude AMPLITUDE] [--framerate FRAMERATE]
* Exécuter ```python3 logstreamer.py``` [--adjust ADJUST ADJUST]
* Lire le fichier wav résultant avec un lecteur audio supportant le format wav [--exclude [EXCLUDE [EXCLUDE ...]]] --host HOST --port
PORT --user USER --password PASSWORD --mount MOUNT
[--protocol PROTOCOL]
optional arguments:
-h, --help show this help message and exit
--log LOG Le fichier de log à traiter (requis)
--workdir WORKDIR Le répertoire de travail (défaut: /tmp)
--duration DURATION La durée d'une note (défaut: 0.008)
--amplitude AMPLITUDE
Le niveau sonore (défaut: 0.5)
--framerate FRAMERATE
Le taux d'échantillonage (défaut: 44100)
--adjust ADJUST ADJUST
Facteurs d'ajustement (défaut: 5000 20000)
--exclude [EXCLUDE [EXCLUDE ...]]
Liste des caractères non traités (défaut: [])
--host HOST Server Icecast2 (requis)
--port PORT Port TCP sur lequel contacter le serveur Icecast2
(requis)
--user USER Nom d'utilisateur (requis)
--password PASSWORD Mot de passe (requis)
--mount MOUNT Point de montage Icecast2 (requis)
--protocol PROTOCOL Protocol à utiliser (défaut: http)
```
## TODO ## TODO

View File

@ -1,35 +1,13 @@
#!/bin/env python3 #!/bin/env python3
""" import os
# Prérequis
* python3
* pigtail
```
pip3 install pigtail
```
# Utilisation
* Ajuster les valeurs des constantes LOG et WAV_OUTPUT en fonction des besoins
* LOG: Le log à jouer
* WAV_OUTPUT: Le fichier wav de sortie
* MAX_DURATION: La durée maximale d'une note
* EXCLUDE: Les caractères dont les valeurs sont ajoutées à cette liste ne seront pas traités
* Exécuter python3 text2wav.py
* Lire le fichier wav résultant avec un lecteur audio supportant le format wav
"""
import wave import wave
import math import math
import shout
import struct import struct
import random import random
from pygtail import Pygtail import argparse
import subprocess
LOG = '/var/log/httpd/access_log'
WAV_OUTPUT = '/home/doug/test/test.wav'
MAX_DURATION = 0.08
EXCLUDE = []
def sine_wave(frequency=444, framerate=44100, amplitude=0.5, duration=1): def sine_wave(frequency=444, framerate=44100, amplitude=0.5, duration=1):
""" """
@ -51,25 +29,85 @@ def sine_wave(frequency=444, framerate=44100, amplitude=0.5, duration=1):
return struct.pack('<{}h'.format(len(data)), *data) return struct.pack('<{}h'.format(len(data)), *data)
def notes_table(oord): def notes_table(oord):
freq = math.floor(math.log(oord)*5000-20000) freq = math.fabs(math.floor(math.log(oord)*int(args.adjust[0])-int(args.adjust[1])))
duration = MAX_DURATION duration = args.duration
return (freq, duration) return (freq, duration)
with wave.open(WAV_OUTPUT, 'wb') as wave_file: def convert2ogg(wav_file, ogg_file):
result = subprocess.call(['oggenc', wav_file, '-o {} --utf8 -t {}'.format(ogg_file, args.log)])
return result
def push_ogg(ogg_file):
icecast = shout.Shout()
icecast.host = args.host
icecast.port = args.port
icecast.user = args.user
icecast.password = args.password
icecast.mount = args.mount
icecast.protocol = args.protocol
icecast.format = 'ogg'
print("Connecting to {}://{}:{}/{}".format(args.protocol, args.host, args.port, args.mount))
icecast.open()
with open(ogg_file, 'rb') as ogg:
total = 0
print("- Reading 4096 bytes")
new_buff = ogg.read(4096)
while True:
cur_buff = new_buff
print("- Reading next 4096 bytes")
new_buff = ogg.read(4096)
total += len(cur_buff)
if len(cur_buff) == 0:
print(" - Buffer is empty: EOF")
print(" - Sent: {} bytes".format(total))
break
print("- Sending 4096 bytes")
icecast.send(cur_buff)
icecast.sync()
def main():
wav_output = "{}.wav".format(os.path.basename(args.log).split('.')[0])
wav_output = os.path.join(args.workdir, wav_output)
ogg_output = "{}.ogg".format(os.path.basename(args.log).split('.')[0])
ogg_output = os.path.join(args.workdir, ogg_output)
with wave.open(wav_output, 'wb') as wave_file:
nchannels = 1 nchannels = 1
sampwidth = 2 sampwidth = 2
framerate = 44100 framerate = args.framerate
wave_file.setnchannels(nchannels) wave_file.setnchannels(nchannels)
wave_file.setsampwidth(sampwidth) wave_file.setsampwidth(sampwidth)
wave_file.setframerate(framerate) wave_file.setframerate(framerate)
try: try:
for line in Pygtail(LOG): with open(args.log, 'r') as log:
for letter in line: for letter in log.read():
oord = ord(letter) oord = ord(letter)
freq, duration = notes_table(oord) freq, duration = notes_table(oord)
if oord not in EXCLUDE: if oord not in args.exclude:
print("Caractère: {} | Ord: {} | Fréquence: {} | Durée: {}".format(letter, oord, freq, duration)) print("Caractère: {} | Ord: {} | Fréquence: {} | Durée: {}".format(letter, oord, freq, duration))
wave_file.writeframes(sine_wave(frequency=freq, duration=duration)) wave_file.writeframes(sine_wave(frequency=freq, duration=duration))
result = convert2ogg(wav_output, ogg_output)
if result == 0:
push_ogg(ogg_output)
else:
raise Exception("Erreur lors de la conversion en OGG: {}".format(result))
except Exception as e: except Exception as e:
print('\033[91m{}\033[0m'.format(e)) print('\033[91m{}\033[0m'.format(e))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--log', help='Le fichier de log à traiter (requis)', type=str, required=True)
parser.add_argument('--workdir', help='Le répertoire de travail (défaut: /tmp)', type=str, default='/tmp')
parser.add_argument('--duration', help="La durée d'une note (défaut: 0.008)", type=float, default=0.08)
parser.add_argument('--amplitude', help="Le niveau sonore (défaut: 0.5)", type=float, default=0.5)
parser.add_argument('--framerate', help="Le taux d'échantillonage (défaut: 44100)", type=int, default=44100)
parser.add_argument('--adjust', help="Facteurs d'ajustement (défaut: 5000 20000)", nargs=2, default=[5000, 20000])
parser.add_argument('--exclude', help="Liste des caractères non traités (défaut: [])", nargs="*", default=[])
parser.add_argument('--host', help="Server Icecast2 (requis)", type=str, required=True)
parser.add_argument('--port', help="Port TCP sur lequel contacter le serveur Icecast2 (requis)", type=int, required=True)
parser.add_argument('--user', help="Nom d'utilisateur (requis)", type=str, required=True)
parser.add_argument('--password', help="Mot de passe (requis)", type=str, required=True)
parser.add_argument('--mount', help="Point de montage Icecast2 (requis)", type=str, required=True)
parser.add_argument('--protocol', help="Protocol à utiliser (défaut: http)", type=str, default='http')
args = parser.parse_args()
main()

0
plip Normal file
View File