forked from jacobdavidson/timestamped_audio_recorder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaudio_recorder.py
98 lines (86 loc) · 3.94 KB
/
audio_recorder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import sounddevice as sd
from scipy.io.wavfile import write
from datetime import datetime, timezone
import numpy as np
import argparse
import sys
from pathlib import Path
# Function to convert datetime to formatted string
def dt_to_str(dt):
"""Converts a datetime object to a formatted string."""
isoformat = "%Y-%m-%dT%H_%M_%S"
dt_str = dt.strftime(isoformat)
if dt.microsecond != 0:
dt_str += ".{:06d}".format(dt.microsecond)
if dt.tzinfo is not None and dt.utcoffset().total_seconds() == 0:
dt_str += "Z"
return dt_str
else:
return dt_str
# Function to generate timestamped filename
def get_timestamped_filename(prefix, output_dir, use_utc=False):
if use_utc:
now = datetime.now(timezone.utc)
else:
now = datetime.now()
timestamp_str = dt_to_str(now)
filename = f"{prefix}_{timestamp_str}.wav"
return output_dir / filename
# Function to record audio chunk
def record_audio_chunk(duration, fs, channels, device=None):
print(f"Recording audio chunk for {duration} seconds...")
try:
audio_data = sd.rec(int(duration * fs), samplerate=fs, channels=channels, dtype='int16', device=device)
sd.wait() # Wait for the recording to finish
except Exception as e:
print(f"An error occurred during recording: {e}")
sys.exit(1)
return audio_data
# Function to save audio data to a file
def save_audio(filename, fs, audio_data):
try:
write(filename, fs, audio_data)
print(f"Recording saved as {filename}")
except Exception as e:
print(f"An error occurred while saving the file: {e}")
sys.exit(1)
# Main function
def main():
parser = argparse.ArgumentParser(description="Continuous Audio Recording Script")
parser.add_argument('-d', '--duration', type=float, default=60, help='Duration of each recording chunk in seconds')
parser.add_argument('-t', '--total-duration', type=float, help='Total duration of recording in seconds (default: runs indefinitely until cancelled)')
parser.add_argument('-r', '--samplerate', type=int, default=44100, help='Sampling rate in Hz')
parser.add_argument('-c', '--channels', type=int, default=2, help='Number of audio channels')
parser.add_argument('--device', type=int, help='Device index for recording')
parser.add_argument('--print-devices', action='store_true', help='Print list of audio devices and exit')
parser.add_argument('--prefix', type=str, default='audio_recording', help='Custom prefix for the filename')
parser.add_argument('--use-utc', action='store_true', help='Use UTC time for the filename timestamp (default is local time)')
parser.add_argument('--output-dir', type=str, default='.', help='Output directory for the recording files')
args = parser.parse_args()
if args.print_devices:
print("Available audio devices:")
print(sd.query_devices())
sys.exit(0)
# Create output directory if it doesn't exist
output_dir = Path(args.output_dir)
if not output_dir.exists():
output_dir.mkdir(parents=True, exist_ok=True)
start_time = datetime.now()
elapsed_time = 0
try:
while True:
# Check if total duration is specified and if elapsed time exceeds it
if args.total_duration and elapsed_time >= args.total_duration:
print("Total recording duration reached. Exiting.")
break
filename = get_timestamped_filename(args.prefix, output_dir, use_utc=args.use_utc)
audio_data = record_audio_chunk(args.duration, args.samplerate, args.channels, device=args.device)
save_audio(filename, args.samplerate, audio_data)
elapsed_time = (datetime.now() - start_time).total_seconds()
except KeyboardInterrupt:
print("\nRecording interrupted by user. Exiting.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
sys.exit(1)
if __name__ == "__main__":
main()