Record a video
IvanViale opened this issue · comments
Hi, i tryed to record a video with the sample in the website, but it doesn't work https://wiki.sipeed.com/soft/maixpy3/zh/usage/Audio/play_mp4.html.
I use chatgpt to create this code, but i receive the below error an i don't know how to solve it.
Can anyone share with me the right code to record a video? Thanks
import av
from maix import camera, image
import numpy as np
# Impostazioni per la registrazione video
output_filename = '/root/output_video.mp4'
frame_width = 640
frame_height = 480
fps = 24
# Configura la fotocamera
camera.config(size=(frame_width,frame_height))
# Configura il codec video
output_options = {
'format': 'mp4',
'pix_fmt': 'yuv420p',
'framerate': fps,
'bit_rate': 4000000, # Bit rate desiderato
}
# Apri il file video per la scrittura
output_container = av.open(output_filename, 'w')
# Aggiungi uno stream video al contenitore di output
output_stream = output_container.add_stream('h264', rate=fps)
output_stream.width = frame_width
output_stream.height = frame_height
output_stream.pix_fmt = 'yuv420p'
output_stream.bit_rate = output_options['bit_rate']
output_stream.options = output_options
try:
# Ciclo di cattura e scrittura dei frame
while True:
# Cattura l'immagine dalla fotocamera
img = camera.capture()
numpydata = np.asarray(img)
# Converte l'immagine in un formato compatibile con av.VideoFrame
frame = av.VideoFrame.from_ndarray(numpydata , format='rgb8')
# Scrivi il frame nel contenitore di output
for packet in output_stream.encode(frame):
output_container.mux(packet)
finally:
# Chiudi la fotocamera e il contenitore di output
camera.close()
for packet in output_stream.encode():
output_container.mux(packet)
output_container.close()
ERROR :
========= Remote Traceback (1) =========
Traceback (most recent call last):
File "<string>", line 40, in <module>
File "av/video/frame.pyx", line 414, in av.video.frame.VideoFrame.from_ndarray
File "av/utils.pyx", line 70, in av.utils.check_ndarray
ValueError: Expected numpy array with dtype `uint8` but got `object`
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.8/site-packages/rpyc/core/protocol.py", line 324, in _dispatch_request
File "/usr/lib/python3.8/site-packages/rpyc/core/protocol.py", line 592, in _handle_call
File "<string>", line 49, in <module>
File "av/stream.pyx", line 153, in av.stream.Stream.encode
File "av/codec/context.pyx", line 482, in av.codec.context.CodecContext.encode
File "av/codec/context.pyx", line 285, in av.codec.context.CodecContext.open
File "/usr/lib/python3.8/_collections_abc.py", line 832, in update
TypeError: Argument 'value' has incorrect type (expected str, got int)
Hi, i was able to record a video with the code below, using pillow=True in the camera.capture(pillow=True) function, but the frame rate is very low, how can i increase it?
import numpy as np
from maix import camera
import av
duration = 4
fps = 24
total_frames = duration * fps
# Configura il codec video
output_options = {
'format': 'mp4',
'pix_fmt': 'yuv420p',
'framerate': fps,
'bit_rate': 4000000, # Bit rate desiderato
}
container = av.open("/root/test1.mp4", mode="w")
# mpeg4
stream = container.add_stream("mpeg4", rate=fps)
stream.width = 1280
stream.height = 720
stream.pix_fmt = "yuv420p"
#stream.bit_rate = output_options['bit_rate']
#stream.options = output_options
camera.config(size=(stream.width,stream.height))
for frame_i in range(total_frames):
print("Frame")
img = camera.capture(pillow=True)
numpydata = np.array(img)
frame = av.VideoFrame.from_ndarray(numpydata, format="rgb24")
for packet in stream.encode(frame):
container.mux(packet)
# Flush stream
for packet in stream.encode():
container.mux(packet)
# Close the file
container.close()
I made a separate test with this simple code to test the framerate
from maix import camera
import time
width= 1280
height= 720
camera.config(size=(width,height))
while True:
start_time = time.time()
img = camera.capture(pillow=True)
#display.show(img)
print("FPS: ", 1.0 / (time.time() - start_time)) # FPS = 1 / time to process loop
and i got this results
[ rpyc-kernel ]( running at Fri Aug 18 08:21:34 2023 )
[camera] config input size(1280, 720)
FPS: 3.564402746617717
FPS: 3.787287951175157
FPS: 3.662776522203864
FPS: 5.015190357757796
FPS: 3.5689461225198302
FPS: 3.0321921145585278
FPS: 5.142038203285811
FPS: 4.453786027763531
FPS: 3.0478183591223735
FPS: 5.204716416873277
FPS: 5.290154139932976
FPS: 3.3642953338825117
FPS: 4.831819035342067
FPS: 4.688321849975632
FPS: 3.6132780497638275
FPS: 4.106804424922599
FPS: 4.133455403012257
FPS: 4.367938282610326
FPS: 4.1519828389228595
FPS: 3.8195837374385873
Can I reach in python 30fps in 720p quality video, or i need to switch in C++?
Thanks
Can anyone help me, please? I can pay