sipeed / MaixPy3

Python sdk for Sipeed Maix-II-Dock(v831). Other board please use https://github.com/sipeed/MaixPy

Home Page:https://wiki.sipeed.com/maixpy3

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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)

commented

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

commented

Can anyone help me, please? I can pay