audio recording functionality for inter-track fills

main
Rob Canning 2024-01-30 14:30:11 +01:00
parent 2a13dfab7a
commit ed3c45afda
4 changed files with 72 additions and 36 deletions

View File

@ -1,14 +1,31 @@
# uho
# uho!
usage examples:
Some python magick to help making the Uho podcast. https://uho.rizom,si
./mk_show.py --episode 2 --date 2024-03-11 --playlist keep --web --art --mp3
## usage examples:
./mk_show.py --episode 2 --insert_fill --top_tail
### create a new playlist
./mk_show.py --episode 2 --date 2024-03-11 --playlist new
./mk_show.py --episode 2 --date 2024-03-11 --playlist edit --web --art --insert_fill --top_tail
### edit an existing playlist
./mk_show.py --episode 2 --playlist edit
when happy with the playlist then record the voice fills:
### record the voice fills for between the songs
each song should have a short intro description and a longer outro description
### record the intros for track 2
./recorder.py -e 2 -f in
### record the outros for track 2
./recorder.py -e 2 -f out
now you have the voice fills and the playlist - time to cook up the show...
### keep the playlist and generate a website artwork and an audiofile output
./mk_show.py --episode 0 --date 2024-1-30 --playlist keep --mp3 --web --art
Generative radio show of contemporary Slovenian independent music for Mariborski radio študent - MARŠ. Scripted using Liquidsoap and assorted other scripting glue, bash, python...
featured labels and artists:
https://pharmafabrik.bandcamp.com/

Binary file not shown.

View File

@ -564,8 +564,8 @@ def create_podcast():
if not os.path.exists(archive_path):
os.makedirs(archive_path)
from distutils.dir_util import copy_tree
copy_tree("archive/blank_fills/", "archive/e/{0}/audio_fills".format(episode_number))
#from distutils.dir_util import copy_tree
#copy_tree("archive/blank_fills/", "archive/e/{0}/audio_fills".format(episode_number))
fill_path = "{0}/{1}/audio_fills".format(archive_path, episode_number)

View File

@ -1,22 +1,17 @@
#!/usr/bin/python3
from pynput import keyboard
import time, os
import pyaudio
import wave
import sched
import sys
#recorder
import pyaudio, wave, sched, sys, time, os
from playsound import playsound
from pynput import keyboard
from threading import Thread, Lock
from pynput import keyboard
import pyaudio
import wave
import sys, os, datetime, fnmatch, glob, random, time, pathlib, re,\
sqlite3, json, subprocess, uuid, argparse, contextlib
from pydub import AudioSegment
from datetime import timedelta
from os.path import join
from tinytag import TinyTag
@ -29,6 +24,17 @@ from glob import glob
import tkinter as tk
from tkinter import filedialog as fd
p = pyaudio.PyAudio()
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
for i in range(0, numdevices):
if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
print("Input Device id ", i, " - ", p.get_device_info_by_host_api_device_index(0, i).get('name'))
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--date", help="Show Date")
parser.add_argument("-e", "--episode", help="Episode Number", type=int)
@ -37,7 +43,7 @@ parser.add_argument("-m", "--mp3", action="store_true")
parser.add_argument("-w", "--web", action="store_true")
parser.add_argument("-a", "--art", action="store_true")
parser.add_argument("-i", "--insert_fills", action="store_true")
parser.add_argument("-t", "--top_tail", action="store_true")
parser.add_argument("-f", "--fill", help="fill type", type=str)
args = parser.parse_args()
@ -51,9 +57,8 @@ episode_author="Rob Canning"
show_short_description = '''The UhO! podcast presents an eclectic selection of independent music from Slovenia. The show aims to deliver as broad a range of genres as possible; banging techno, sludge, math rock, contemporary classical, doom, free improvisation, noise music, glitch, jazz skronk, field recordings, ambient, drone....etc etc... whatever the genre, you can be sure you are listening to the latest and most inovative music on offer in this part of the world. Hosted and compiled by Rob Canning, the show is published weekly by Zavod Rizoma and is broadcast in Slovenia on FM by mariborski radio študent: MARŠ. It as also available as a podcast. Use our RSS feed or search for UhO Podcast where ever you subscribe to podcasts'''
episode_number = args.episode
fill = args.fill;
input_date = args.date
episode_date = datetime.datetime.now().strftime("%Y-%m-%d")
episode_duration = 10
@ -71,7 +76,7 @@ if not os.path.exists(fill_path):
#TODO lookup metadata from music_db not from episodoe = use uuids!
#TODO scrape artist bio from bandcamp?
#TODO GET VARIATION PROMPTS
#TODO GET VARIATION PROMPT
def get_playlist_for_fill_recording(conn, episode_number, episode_duration):
cursor = conn.cursor()
@ -80,7 +85,7 @@ def get_playlist_for_fill_recording(conn, episode_number, episode_duration):
cursor.execute('SELECT SUM(trackdur) FROM EPISODES WHERE EPISODE=? ', [episode_number])
episode_duration = cursor.fetchone()[0]
os.system("clear")
# os.system("clear")
print("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
print(">> PROPOSED EPISODE #{0} PLAYLIST: ({1}) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"\
.format(episode_number, timedelta(seconds=round(episode_duration))))
@ -95,7 +100,7 @@ def get_playlist_for_fill_recording(conn, episode_number, episode_duration):
user_input = input('''
(l)isten to track
R ECORD OUTRO FILL
R ECORD FILL
>>>>>>>>>>>>>>>>>>>>>>>>>>> OR PRESS ENTER TO PROCEED................... : ''')
@ -103,13 +108,22 @@ def get_playlist_for_fill_recording(conn, episode_number, episode_duration):
playlist_preview_track(conn, episode_number, episode_duration)
elif user_input == "r":
num = input("Which TRACK # to record outro fill for : ")
the_file = "archive/e/{0}/audio_fills/{1}_out.wav".format(episode_number, num)
if fill == "out":
num = input("Which TRACK # to record OUTRO fill for : ")
the_file = "archive/e/{0}/audio_fills/{1}_out.wav".format(episode_number, num)
elif fill == "in":
num = input("Which TRACK # to record INTRO fill for : ")
the_file = "archive/e/{0}/audio_fills/{1}_in.wav".format(episode_number, num)
else:
print("must speficy in or out")
print(the_file)
r = recorder(the_file)
p = player(the_file)
l = listener(r, p)
os.system("clear")
#os.system("clear")
for i in preview[int(num)-1:int(num)]:
print('''
@ -157,12 +171,15 @@ class player:
#contents of the run function are processed in another thread so we use the blocking
# version of pyaudio play file example: http://people.csail.mit.edu/hubert/pyaudio/#play-wave-example
def run(self):
with self.lock:
self.playing += 1
with wave.open(self.wavfile, 'rb') as wf:
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
input_device_index=4,
output_device_index=4,
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True)
@ -195,7 +212,7 @@ class recorder:
self.channels = channels
self.rate = rate
self.recording = False
self.pa = pyaudio.PyAudio()
self.p = pyaudio.PyAudio()
def start(self):
#we call start and stop from the keyboard listener, so we use the asynchronous
@ -204,7 +221,7 @@ class recorder:
if not self.recording:
self.wf = wave.open(self.filename, 'wb')
self.wf.setnchannels(self.channels)
self.wf.setsampwidth(self.pa.get_sample_size(self.dataformat))
self.wf.setsampwidth(self.p.get_sample_size(self.dataformat))
self.wf.setframerate(self.rate)
def callback(in_data, frame_count, time_info, status):
@ -212,14 +229,16 @@ class recorder:
self.wf.writeframes(in_data)
return (in_data, pyaudio.paContinue)
self.stream = self.pa.open(format = self.dataformat,
channels = self.channels,
rate = self.rate,
input = True,
stream_callback = callback)
self.stream = self.p.open(format = self.dataformat,
input_device_index=4,
output_device_index=4,
channels = self.channels,
rate = self.rate,
input = True,
stream_callback = callback)
self.stream.start_stream()
self.recording = True
print('recording started')
print('recording started',end='')
def stop(self):
if self.recording:
@ -228,7 +247,7 @@ class recorder:
self.wf.close()
self.recording = False
print('recording finished')
print('recording finished',end='')
class listener(keyboard.Listener):