-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtom.py
More file actions
135 lines (117 loc) · 4.66 KB
/
tom.py
File metadata and controls
135 lines (117 loc) · 4.66 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/opt/rec/bin/python
# Author: Rhys Gough of the Karigo Lab
# Usage: ./v_tom.py <recording name> <recording length>
# A preview window will open to ensure the camera is position fine.
# The preview window will close and the recording starts after indicating
# whether the user wants to record audio on a connected pi.
from picamera2 import Picamera2, Preview, controls
from picamera2.encoders import H264Encoder, MJPEGEncoder, Quality
from picamera2.outputs import FfmpegOutput, FileOutput
from libcamera import controls
import sounddevice as sd
import soundfile as sf
import queue
import sys
from datetime import datetime # what a dumb import
import time
import subprocess
# From the Picamera 2 Docs:
# Every camera frame may not take less than the first value
# nor longer than the second. FR = 1000000 / frame_duration. Common settings:
# 10 FPS = (100000, 100000), 30 FPS = (33333, 33333), 25 FPS (40000, 40000)
# how long to record before starting next track
# (note that wav files cap out at 2 GB or ~2 hours at 250000 Hz)
def recA(fname, dur, fs=250000, ch=1, mic_key = 'ltramic'):
try:
dev_i = sd.query_devices(device=mic_key)['index']
#apparent bug on linux where the only available sampling rate is the mic's default
except ValueError:
print('unable to find Ultramic, trying default device')
print(sd.query_devices())
dev_i = 0
fs = int(sd.query_devices(0)['default_samplerate'])
ch = 1
q = queue.Queue()
def callback(indata, frames, time, status):
#This is called (from a separate thread) for each audio block.
if status:
print(status, file=sys.stderr)
q.put(indata.copy())
q.put(indata.copy())
t = time.time()
try:
with sf.SoundFile(fname+".flac", mode='w', samplerate=fs, channels=ch, subtype='PCM_S8') as f: #potentially should change w to x in final app to prevent overwritting
with sd.InputStream(samplerate = fs, device = dev_i, channels = ch, callback = callback):
print("recording audio, interrupt to stop")
while time.time()-t < dur:
f.write(q.get())
except KeyboardInterrupt:
print("\ninterrupted")
print("finished recording "+fname)
# subprocess.Popen("scp {} {}".format(fname, storage)
def recAV(picam, fname, dur, enc, a='n'):
out = FfmpegOutput(fname+'.mp4')
picam.start_encoder(enc, out, quality=Quality.LOW)
picam.start()
print('recording ' + fname)
if a == 'y':
recA(fname, dur)
else:
time.sleep(dur)
picam.stop()
picam.stop_encoder()
def rTran(file, adrs):
for attempt in range(5):
try:
subprocess.Popen("rsync {}.* {}".format(file, adrs), shell=True)
except:
print('transfer failed {}'.format(attempt))
time.sleep(1)
else:
break
if __name__=='__main__':
sz= (640, 480)
frame_duration=(100000, 100000)
exposure=1000
sharpness=4
seg=3600
auto = 'a'
transfer = 't'
### setup section ###
# fname = sys.argv[1]
# t = int(sys.argv[2])
picam = Picamera2()
cam_config = picam.create_video_configuration({'size': sz, 'format': 'YUV420'}, controls={'FrameDurationLimits': frame_duration, 'ExposureTime': exposure, 'Saturation': 0, 'NoiseReductionMode': controls.draft.NoiseReductionModeEnum.Off, 'Sharpness': sharpness})
picam.configure(cam_config)
encoder = H264Encoder()
print('Adjust camera as desired. Recording will start after audio selection')
print('Alternatively, cancel now with Ctrl+C')
picam.start_preview(Preview.QT) #inefficient way to preview, but necessary to view over ssh
picam.start()
fname = input("File prefix: ")
t = int(input("Time in seconds to record: "))
while not(auto.lower() == 'y' or auto.lower() == 'n'):
auto = input('Record with audio? (y/n) ')
while not(transfer.lower() == 'y' or transfer.lower() == 'n'):
transfer = input('Transfer files? (y/n) ')
try:
picam.stop_preview()
except:
pass
picam.stop()
### recording section ###
if transfer.lower() == 'y':
transfer_address = input('Transfer address: ')
i = 0
while i < t//seg:
i_fname = '{}_{}_{:%m%d%y-%H%M%S}'.format(fname, str(i), datetime.now())
recAV(picam, i_fname, seg, encoder, a=auto.lower())
if transfer == 'y':
rTran(i_fname, transfer_address)
i += 1
ft = t%seg
if ft != 0:
i_fname = '{}_{}_{:%m%d%y-%H%M%S}'.format(fname, str(i), datetime.now())
recAV(picam, i_fname, ft, encoder, a=auto.lower())
if transfer == 'y':
rTran(i_fname, transfer_address)