Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

Record a video #45

Open
IvanViale opened this issue Aug 16, 2023 · 2 comments
Open

Record a video #45

IvanViale opened this issue Aug 16, 2023 · 2 comments

Comments

@IvanViale
Copy link

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)

@IvanViale
Copy link
Author

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

@IvanViale
Copy link
Author

Can anyone help me, please? I can pay

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant