-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
130 lines (115 loc) · 4.23 KB
/
main.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
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
"""
This code is the main function to record desktop screenshot and save it as a video.
"""
import cv2
import numpy as np
import pyautogui as pg
import subprocess
import threading
import msvcrt
import math
import os
from pathlib import Path
import pyaudio
import argparse
from pydub import AudioSegment
from videorecord import ScreenRecorder
from audiorecord import AudioRecorder
def timing_adjust(vrec, arec):
timing_adjustment = vrec.elapsed_time - arec.elapsed_time
if timing_adjustment < 0:
print("WARNING: Your recorded audio time is shorter than video time.")
return 0
else:
print("Adjust timing of audio by delaying (s)", timing_adjustment)
return timing_adjustment
def insert_silent(timing_adjustment, aoutput_name):
# apply audio delay
# create silent audio segment
silent_segment = AudioSegment.silent(
duration=math.ceil(timing_adjustment * 1000)
) # duration in milliseconds
# read wav file to an audio segment
audio_segment = AudioSegment.from_wav(aoutput_name)
# add above two audio segments
delay_segment = silent_segment + audio_segment
# save modified audio
delay_segment.export(aoutput_name, format="wav")
def video_audio_merge(moutput_name, aoutput_name, voutput_name):
# cmd line
cmd = (
"ffmpeg.exe -y -i "
+ aoutput_name
+ " -i "
+ voutput_name
+ " -pix_fmt yuv420p "
+ moutput_name
)
subprocess.call(cmd, shell=True)
def video_convert(moutput_name, voutput_name):
# cmd line
cmd = "ffmpeg.exe -y -i " + voutput_name + " -pix_fmt yuv420p " + moutput_name
subprocess.call(cmd, shell=True)
def encode_video(set_fps, recorded_fps, voutput_name):
cmd = "ffmpeg.exe -y -r " + str(recorded_fps) + " -i " + str(voutput_name) + " -pix_fmt yuv420p -r " + str(set_fps) + " re_" + str(voutput_name)
subprocess.call(cmd, shell=True)
os.remove(str(voutput_name))
os.rename("re_"+str(voutput_name), str(voutput_name))
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--fps", type=float, default=3.0, help="frame per second for video recording"
)
parser.add_argument(
"--output", type=str, default="record.mp4", help="recorded video name and type"
)
parser.add_argument(
"--index", type=int, default=5, help="device index being recorded for audio"
)
opt = parser.parse_args()
print(opt)
# frame per second
FPS = opt.fps
# temporary output video name and type
voutput_name = "video.mp4"
# temporary output audio name and type
aoutput_name = "audio.wav"
# select audio device index
device_index = (
opt.index
) # default select device name: 'Speakers (Conexant ISST Audio)'
# merge video + audio name and type
moutput_name = opt.output
# create screen recorder object
vrec = ScreenRecorder(output_name=voutput_name, fps=FPS)
# create audio recorder object
arec = AudioRecorder(
output_name=aoutput_name, input_device_index=device_index, fps=FPS
)
# start recording with both video and audio threads
print("Start recording......")
vrec.start()
arec.start()
while True:
# catch keyboard key 'q' to stop recording
if msvcrt.kbhit() and msvcrt.getch() == b"q":
print("Stop recording......")
vrec.stop()
arec.stop()
# re-encode video according to measured video length
if Path(voutput_name).is_file():
encode_video(vrec.fps, vrec.recorded_fps, voutput_name)
# merge video and audio
if len(arec.audio_frames) != 0 and Path(aoutput_name).is_file() and Path(voutput_name).is_file():
timing_adjustment = timing_adjust(vrec, arec)
insert_silent(timing_adjustment, aoutput_name)
print("Merge video and audio......")
video_audio_merge(moutput_name, aoutput_name, voutput_name)
elif Path(voutput_name).is_file():
print("No sound recorded. Transfer video......")
video_convert(moutput_name, voutput_name)
else:
print("No sound and no video recorded.")
break
if __name__ == "__main__":
main()