-
Notifications
You must be signed in to change notification settings - Fork 1
/
read_and_feed.py
85 lines (78 loc) · 2.58 KB
/
read_and_feed.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
import os
import sys
from collections import deque
from datetime import datetime, timedelta
from pathlib import Path
from subprocess import Popen, PIPE, DEVNULL
from time import sleep
from dotenv import load_dotenv
load_dotenv()
def main(camera_name="output"):
media_dir = (Path(__file__) / ".." / "media" / camera_name).resolve()
media_dir.mkdir(exist_ok=True, parents=True)
for file in media_dir.glob("*"):
file.unlink()
resolution = os.environ["RESOLUTION"] or "1920x1080"
# Example of looping a single file and drawing the frame number in the middle
# [
# 'ffmpeg',
# '-f', 'rawvideo',
# '-pix_fmt', "yuv420p",
# '-s:v', resolution,
# '-stream_loop', "-1",
# '-i', '/home/jovasa/Downloads/BasketballDrive_1920x1080_50_500.yuv',
# '-vf', rf"drawtext=fontsize=100:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text=%{{n}}",
# '-f', "rawvideo",
# '-pix_fmt', "yuv420p",
# '-'
# ]
a = Popen(
[
'ffmpeg',
'-f', 'lavfi',
'-i', f'color=c=black:size={resolution}',
'-vf', rf"drawtext=fontsize=100:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text=%{{n}}",
'-f', "rawvideo",
'-pix_fmt', "yuv420p",
'-'
],
stdout=PIPE,
stderr=DEVNULL
)
i = 0
width, height = [int(x) for x in resolution.split("x")]
segments = deque()
while True:
segment_start_time = datetime.utcnow()
output_file = media_dir / f'output_{segment_start_time.isoformat()}.mp4'
b = Popen(
[
'ffmpeg',
'-s:v', resolution,
'-f', 'rawvideo',
'-pix_fmt', 'yuv420p',
'-r', '30',
'-i', 'pipe:.yuv',
"-c:v", "libx264",
str(output_file),
"-y"
],
stdin=PIPE,
stderr=DEVNULL
)
for _ in range(30 * 10):
f = a.stdout.read(int(width * height * 1.5))
b.stdin.write(f)
b.stdin.close()
i += 1
segments.append(output_file)
if len(segments) > 60:
segment_to_remove = segments.popleft()
segment_to_remove.unlink()
segment_end_time = datetime.utcnow()
# This is not needed if the input is from actual camera
sleep(10 - (segment_end_time - segment_start_time).total_seconds())
a.stdout.close()
if __name__ == '__main__':
camera = sys.argv[1] if len(sys.argv) > 1 else "output"
main(camera)