Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HOW-TO] Don't take a photo after record #988

Open
tranhien1612 opened this issue Mar 21, 2024 · 17 comments
Open

[HOW-TO] Don't take a photo after record #988

tranhien1612 opened this issue Mar 21, 2024 · 17 comments

Comments

@tranhien1612
Copy link

tranhien1612 commented Mar 21, 2024

Hi, i am using picame2 to write a simple code to take a photo and record video. Receiver the data from TCPClient and capture or record.

import time
import os
import socket
import threading
from datetime import datetime

from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput
from picamera2.outputs import FileOutput

picam2 = Picamera2();
isRecord = False;
isPhoto = False;
  
def camera():
  global picam2;
  global isRecord;
  global isPhoto;
  
  print("Start Camera")
  picam2.configure(picam2.create_video_configuration())
  picam2.start()
  
  try:
    while True:

      if(isPhoto):
        print("Start Photo")
        filename = "/home/raspi/img/"+ datetime.now().strftime("%d-%m-%Y-%H-%M-%S") + ".jpg";
        #picam2.start_and_capture_file(filename)

        #cfg = picam2.create_still_configuration()
        #picam2.switch_mode_and_capture_file(cfg, filename)
        
        picam2.capture_file(filename)
        isPhoto = False;
        
      if(isRecord):
        print("Start Video")
        filename = "/home/raspi/video/"+ datetime.now().strftime("%d-%m-%Y-%H-%M-%S") + ".mp4";
        #picam2.video_configuration.format = 'BGR888';
        picam2.start_and_record_video(filename, duration=900); #15p
    
  except Exception as e:
    print(f"Error: {str(e)}")

def handle_client(client_socket, client_addr):
    print(f"Connection from {client_addr}")
    thread = threading.Thread(target=camera, name='camera')
    thread.start()
    
    global picam2;
    global isRecord;
    global isPhoto;
    try:
        while True:
            # Receive data from the client
            data = client_socket.recv(1024)
            
            if not data:
                break  # No more data received, exit loop
            dataHexa = data.hex();
            #print(dataHexa)
            if(dataHexa == '01'):
              isPhoto = True;
            elif(dataHexa == '02' and isRecord == False):
              isRecord = True;
            elif(dataHexa == '03' and isRecord == True):
              print("Stop Video")
              picam2.stop_recording()
              isRecord = False;
            
            # Echo back the received data
            #client_socket.sendall(data)
    except Exception as e:
        print(f"Error: {str(e)}")
    finally:
        # Close the client socket
        client_socket.close()
        print(f"Connection with {client_addr} closed")
        thread.join()

def start_server(host, port):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen(5)  # Accept up to 5 connections
    print(f"TCP server started on {host}:{port}")
    while True:
        # Wait for a client to connect
        print("Waiting for connection...")
        client_socket, client_addr = server_socket.accept()
        
        # Start a new thread to handle the client connection
        client_thread = threading.Thread(target=handle_client, args=(client_socket, client_addr))
        client_thread.start()

if __name__ == "__main__":
    start_server('0.0.0.0', 5765) 

when I record, then stop recording. After that I couldn't record or take photos.
It seems that when using the recording command and stopping recording, subsequent commands cannot be executed
pls support me to fix it.

@davidplowman
Copy link
Collaborator

Hi, it would be easier if you could condense your example to maybe a dozen lines or so, basically the simplest thing you can manage that shows the problem. Otherwise we have to spend time working out how to run your code and figure out exactly what the code is doing. Would that be possible?

Having said that, I see you're using the start_and_... methods. I really would avoid that - they were put on only for folks who "just want to call one function" and don't really want any control over it. But if you can create a very short standalone script that demonstrates the problem, then that would be great and would make it obvious how to reproduce the issue. I'm thinking something like:

from picamera2 import Picamera2

picam2 = Picamera2()
picam2.start_and_record_video("test.h264", duration=10)
picam2.start_and_capture_file("test.jpg")

Thanks!

@tranhien1612
Copy link
Author

tranhien1612 commented Mar 21, 2024

@davidplowman I have a simple code. But when i run code, i only record one time (don't take photo and record after first time)

  • record1(test.mp4) is successful but photo2, record2 to end not run
#!/usr/bin/python3
import time

from picamera2 import Picamera2
from picamera2.encoders import H264Encoder
from picamera2.outputs import FfmpegOutput

picam2 = Picamera2()
picam2.configure(picam2.create_video_configuration())

print("Start Record1")
picam2.start_and_record_video("test.mp4", duration=5);

print("Photo2")
picam2.capture_file("test1.jpg")
time.sleep(1)
print("Start Record2")
picam2.start_and_record_video("test1.mp4", duration=5);

print("Photo3")
picam2.capture_file("test2.jpg")
time.sleep(1)
print("Start Record3")
picam2.start_and_record_video("test2.mp4", duration=5);

@davidplowman
Copy link
Collaborator

Hi again, and thanks for the simplified script. I just wanted to check that you know that start_and_record_video will wait for the recording to finish, and then stop the camera. After that, I expect picam2.capture_file("test1.jpg") will lock up because it's waiting for the camera which is no longer running.

Are you wanting to take pictures simultaneously with video, or one after the other?

@tranhien1612
Copy link
Author

@davidplowman Yes, I want to test the functions when taking pictures and recording videos sequentially.
I have a question: when executing the start_and_record_video function, if I call stop_recording while the start_and_record_video function is being executed, will I still take photos or record videos afterward?

@tranhien1612
Copy link
Author

@davidplowman I want to be able to take photos, record and stop video recording at any time. Can you suggest me a list of functions to perform this task?
In addition, I also want to stream video through rtsp, but I still haven't found an example for this idea

@davidplowman
Copy link
Collaborator

I think you'd do better to avoid the start_and_... functions. I would configure and start the camera, and then just leave it running. Then you can use start_encoder and stop_encoder at any time to start recording. You can also use capture_file at any time if the camera is running.

Here are some examples that might help:

@tranhien1612
Copy link
Author

@davidplowman Thanks, I wnat to record with .mp4 file and take photos. I went through your instructions and i have a simple code like below. Is this code what you mean?

import time
from picamera2 import Picamera2
from picamera2.outputs import FfmpegOutput
from picamera2.encoders import H264Encoder

picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)

encoder = H264Encoder(10000000)
output = FfmpegOutput("test.mp4", audio=True)
# Start Record
picam2.start_recording(encoder, output)
time.sleep(10)
picam2.stop_recording()

# Take Photos
picam2.capture_file("test.jpg")

@davidplowman
Copy link
Collaborator

Hi, I think that's close. stop_recording will stop the camera, so either:

  • Use stop_encoder instead. That should leave the camera running.
  • Or start the camera again (picam2.start()) before calling capture_file. There will be a short delay while the camera restarts.

@tranhien1612
Copy link
Author

@davidplowman thank you!. tomorrow, i will test this code. Thank you for your support!

@tranhien1612
Copy link
Author

tranhien1612 commented Mar 27, 2024

@davidplowman i tried the example capture_stream_udp.py, i change ip to my ip latop and received data. i want to change the file format "mkv" or "mov" or "mp4" . Can i change it by code?

@davidplowman
Copy link
Collaborator

I think the FfmpegOutput detects the format from the filename, so many formats other than mp4 should work. Have you tried this?

@tranhien1612
Copy link
Author

@davidplowman I want to record video twice with the command start_recording, but when I stop with the command stop_record, both stop. I want to stop one of the two, how do I do that?

@tranhien1612
Copy link
Author

Tôi nghĩ rằng nó FfmpegOutputphát hiện định dạng từ tên tệp, vì vậy nhiều định dạng khác ngoài mp4 sẽ hoạt động. Bạn đã thử cái này chưa?
i don`t try this command.

@davidplowman
Copy link
Collaborator

If you have started two encoders then use stop_encoder. You should be able to stop one encoder and leave the other running. See for example https://github.com/raspberrypi/picamera2/blob/main/examples/capture_video_multiple_2.py.

@tranhien1612
Copy link
Author

@davidplowman how can i increase the fps when streaming and recording video? Currently, the fps is 11 when i use the picam2.start_encoder for recording and picam2.start_recording(H264Encoder(bitrate=1000000), output=FfmpegOutput( "-f rtp udp://192.168.1.27:10001")); for streaming. I want to increase the fps to 30fps.

@tranhien1612
Copy link
Author

@davidplowman i am using :

        video_config = self.picam2.create_video_configuration(
                    main   ={"size": (1920, 1080)}, 
                    lores  ={"size": (1280, 720)}, 
                    raw    ={"size": (4056, 3040)}, 
                    controls = {"FrameRate": 30.0},
                ); 

main, lorse for recording and streaming and raw for taking photos.
with size windows of raw, i see the fps max is 14 fps.
i changed the size windows of raw to (1920, 1080), then the fps is 30fps.
But i want to take photos with max resolution, but with max resolution of taking photo, the fps is slow.
Can you give me some suggestion?

@davidplowman
Copy link
Collaborator

Hi, I'm afraid that's a physical limitation of the hardware. At full resolution there are too many pixels to achieve 30fps so you have to choose either resolution or framerate.

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

No branches or pull requests

2 participants