Selaa lähdekoodia

added play-all and record-all

Gamaliel Espinoza 8 vuotta sitten
vanhempi
commit
e2fe7abe23
3 muutettua tiedostoa jossa 171 lisäystä ja 2 poistoa
  1. 1 1
      tools/fourier/__init__.py
  2. 169 0
      tools/fourier/cli.py
  3. 1 1
      tools/setup.py

+ 1 - 1
tools/fourier/__init__.py

@@ -1 +1 @@
-__version__ = '1.0.1'
+__version__ = '1.0.2'

+ 169 - 0
tools/fourier/cli.py

@@ -2,12 +2,21 @@ from __future__ import print_function
 from argparse import ArgumentParser
 from hashlib import md5
 from datetime import datetime
+from binascii import hexlify
+from threading import Thread
+from StringIO import StringIO
+from io import BufferedWriter
+from subprocess import PIPE
+import subprocess
 import sqlite3
+import signal
+import curses
 import time
 import json
 import sys
 import os
 
+
 strptime = datetime.strptime
 ARG_DATE_FMT = '%Y-%m-%d %H:%M:%S'
 simple_date = lambda s: strptime(s, ARG_DATE_FMT)
@@ -39,6 +48,9 @@ def hash_file(filename):
                 break
     return ahash.hexdigest()
 
+def parse_stations(string):
+    return string.split(',')
+
 def main():
     parser = ArgumentParser()
     subparsers = parser.add_subparsers(dest='entity')
@@ -57,6 +69,13 @@ def main():
 
     stations_parser = subparsers.add_parser('station')
     stations_parser.add_argument('action')
+    stations_parser.add_argument('-stations', dest='stations',
+                                 type=parse_stations)
+    stations_parser.add_argument('--play-only', dest='play_only',
+                                 action='store_const',
+                                 const=True,
+                                 default=False
+                                 )
 
     args = parser.parse_args()
     action = args.action
@@ -151,7 +170,157 @@ def main():
             for dr in dirs:
                 if '.' not in dr:
                     print(dr)
+
+        elif action == 'record-all' or action == 'play-all':
+            import pyaudio, wave
+
+            if action == 'play-all':
+                args.play_only = True
+
+            audio = pyaudio.PyAudio()
+            stream = audio.open(format=pyaudio.paInt16,
+                                channels=1,
+                                rate=44100,
+                                output=True)
+
+            
+            receivers_count = config['receivers_count']
+            processes = []
+            transcoders = []
+            totals = []
+            basepath = '/var/fourier/tests'
+            env = os.environ
+            stream_index = 0
+
+            if args.stations:
+                stations = args.stations
+                if len(stations) < receivers_count:
+                    for i in range(receivers_count) - len(stations):
+                        receivers_count.append('98.5')
+            else:
+                stations = ['98.5'] * receivers_count
+
+            print(stations)
+
+            if not os.path.isdir(basepath):
+                os.mkdir(basepath)
+
+            test_id = hexlify(os.urandom(4))
+            
+            for index in range(receivers_count):
+                filename = os.path.join(basepath, "{}-{}.mp3"\
+                                        .format(test_id, index)
+                                        )
+
+                if not args.play_only:
+                    ffmpeg = subprocess.Popen([
+                        'ffmpeg', '-f', 's16le', '-i', 'pipe:0',
+                                  '-ac', '1', '-ar', '24000',
+                                  '-ab', '64k',
+                                  '-nostdin',
+                                  '-f', 'mp3', 
+                                  filename,
+                        ],
+                        stdin=PIPE,
+                        stdout=PIPE,
+                        stderr=PIPE,
+                        env=env,
+                        preexec_fn=os.setpgrp,
+                        close_fds=True,
+                    )
+                    transcoders.append(ffmpeg)
+
+                rtl = subprocess.Popen([
+                    'rtl_fm', '-M', 'wbfm', '-g', '10',
+                              '-d', str(index),
+                              '-f', '{}M'.format(stations[index]),
+                              '-o', '4',
+                              '-F', '8',
+                              '-p', '200',
+                              '-s', '88200',
+                              '-r', '44100',
+                    ],
+
+                    stdout=PIPE,
+                    stdin=PIPE,
+                    stderr=PIPE,
+                    env=env,
+                    preexec_fn=os.setpgrp,
+                    close_fds=True,
+                )
+                
+                processes.append(rtl)
+                totals.append(0)
+
+            scr = curses.initscr()
+            scr.addstr(0, 0, 'Sintonizadores')
+            scr.addstr(receivers_count + 2, 0,
+                       'Presiona un número para escuchar'
+                       )
+            if args.play_only:
+                scr.addstr(receivers_count + 3, 0,
+                           'Solo reproduciendo'
+                           )
+            else:
+                scr.addstr(receivers_count + 4, 0,
+                           'Reproduciendo y grabando'
+                           )
+                scr.addstr(receivers_count + 4, 0,
+                           'ID de prueba: /var/fourier/tests/{}-x.mp3'\
+                           .format(test_id)
+                           )
+                scr.addstr(receivers_count + 5, 0,
+                           'Usar --play-only para solo reproducir'
+                           )
+            scr.addstr(stream_index + 1, 0, '>')
+            scr.refresh()
+            scr.timeout(0)
+            curses.noecho()
+            curses.curs_set(0)
+
+            try:
+                while 1:
+                    refresh = False
+                    for index in range(receivers_count):
+                        data = processes[index].stdout.read(4096)
+                        if data:
+                            if index == stream_index:
+                                stream.write(data)
+
+                            if not args.play_only:
+                                transcoders[index].stdin.write(data)
+
+                            totals[index] += len(data)
+
+                            if totals[index] % 10 == 0:
+                                scr.addstr(index + 1, 5, '{:01x} {:>4} {}\n\n'\
+                                    .format(index, stations[index], totals[index])
+                                )
+                                refresh = True
+
+                    k = scr.getch()
+                    if k > -1:
+                        key = int(chr(k), 16) if k > 0 else 0
+                        if key >= 0 and key < receivers_count:
+                            scr.addstr(stream_index + 1, 0, ' ')
+                            stream_index = key
+                            refresh = True
+
+                    if refresh:
+                        scr.addstr(stream_index + 1, 0, '>')
+                        scr.refresh()
                         
+            except KeyboardInterrupt:
+                curses.endwin()
+                for index in range(receivers_count):
+                    if not args.play_only:
+                        transcoders[index].send_signal(signal.SIGINT)
+                    processes[index].send_signal(signal.SIGINT)
+                    
+
+            except Exception as ex:
+                curses.endwin()
+                print(ex)
 
 if __name__ == '__main__':
     main()

+ 1 - 1
tools/setup.py

@@ -13,7 +13,7 @@ setup(
   description = 'Fourier command line tools',
   long_description = 'You can use it for do maintenance stuff',
   scripts = [join(binpath, 'fourier')],
-  install_requires=[],
+  install_requires=['pyaudio', 'curses'],
   author = 'Gamaliel Espinoza M.',
   author_email = 'gamaliel.espinoza@gmail.com',
   url = 'https://git.miralo.xyz/AudioValid/fourier-install',