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
* python3
* pigtail
```
pip3 install pigtail
```
* oggenc
## 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 logstreamer.py```
* Lire le fichier wav résultant avec un lecteur audio supportant le format wav
```
logstreamer.py -h
usage: logstreamer.py [-h] --log LOG [--workdir WORKDIR] [--duration DURATION]
[--amplitude AMPLITUDE] [--framerate FRAMERATE]
[--adjust ADJUST ADJUST]
[--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

View File

@ -1,35 +1,13 @@
#!/bin/env python3
"""
# 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 os
import wave
import math
import shout
import struct
import random
from pygtail import Pygtail
LOG = '/var/log/httpd/access_log'
WAV_OUTPUT = '/home/doug/test/test.wav'
MAX_DURATION = 0.08
EXCLUDE = []
import argparse
import subprocess
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)
def notes_table(oord):
freq = math.floor(math.log(oord)*5000-20000)
duration = MAX_DURATION
freq = math.fabs(math.floor(math.log(oord)*int(args.adjust[0])-int(args.adjust[1])))
duration = args.duration
return (freq, duration)
with wave.open(WAV_OUTPUT, 'wb') as wave_file:
nchannels = 1
sampwidth = 2
framerate = 44100
wave_file.setnchannels(nchannels)
wave_file.setsampwidth(sampwidth)
wave_file.setframerate(framerate)
def convert2ogg(wav_file, ogg_file):
result = subprocess.call(['oggenc', wav_file, '-o {} --utf8 -t {}'.format(ogg_file, args.log)])
return result
try:
for line in Pygtail(LOG):
for letter in line:
oord = ord(letter)
freq, duration = notes_table(oord)
if oord not in EXCLUDE:
print("Caractère: {} | Ord: {} | Fréquence: {} | Durée: {}".format(letter, oord, freq, duration))
wave_file.writeframes(sine_wave(frequency=freq, duration=duration))
except Exception as e:
print('\033[91m{}\033[0m'.format(e))
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
sampwidth = 2
framerate = args.framerate
wave_file.setnchannels(nchannels)
wave_file.setsampwidth(sampwidth)
wave_file.setframerate(framerate)
try:
with open(args.log, 'r') as log:
for letter in log.read():
oord = ord(letter)
freq, duration = notes_table(oord)
if oord not in args.exclude:
print("Caractère: {} | Ord: {} | Fréquence: {} | Durée: {}".format(letter, oord, freq, 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:
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