Ruud14 / SecurityCamera

A Raspberry Pi camera system with a live video feed, motion detection system, H.264 mp4 recording capabilities and a storage management system with support for remote storage. The recorder supports pre-motion frame recording and no internet environments (e.g. Wildlife cameras).
MIT License
71 stars 10 forks source link

legacy versions #11

Closed mohan51 closed 9 months ago

mohan51 commented 1 year ago

Hi @Ruud14 ,

from past few days i am working on your Security camera project for a small kind of poc,I had few implementation issues. 1) What is the Legacy versions you implemented in this project? 2) I saw that you implemented the complete streaming on Pi . is there any other usecase that you tried on client-server architecture? 3) how to start and store the recordings. because when i add 'recorder._start_recording()' after detector.start() in main.py, it is showing error.

mohan51 commented 1 year ago

and also what is the termination condition? because whenever i need to stop the streaming i am using keyboard interrupt but it doesn't stop streaming or stopping the program

mohan51 commented 1 year ago

and when a motion is detected, the recording is started and stopped after 9sec, after that again no motion is detecting if we moving around the camera

Ruud14 commented 1 year ago

Hi @mohan51

I'll try to answer your questions as best as I can.

  1. The legacy versions are just previous, and worse, versions of this project. You should not use them if you're new here, they are merely there for those that started using this project over 3 years ago and are still using the old code.
  2. There are no other things using the client-server architecture except for the streaming and the transfer of files in case of remote storage.
  3. You should not have to modify the code. Everything that you need is configurable in the config.json file. Please only modify the python files if you know what you're doing. I cannot help you with any issues you encounter if you are modifying the pyton files. The recordings will be stored in the local_recordings_output_path (see the documentation by default.

Regarding your other questions: There is no termination condition. If you want to stop streaming, you should just kill the running process. This program is usually just started once (e.g. at startup) and terminated whenever the device (Rb pi) shuts down. Recording sensitivity and duration are all configurable in the config.json file.

Hope this helps :)

Chanti551 commented 1 year ago

Hi @Ruud14 thank you for the reply..actually , I didn't change anything expect the config.json regarding path..when I try to execute the main.py it started and detector also started but after few seconds a normal video is recorded and stored in local..after that the program doesn't catch the other detections..could you please help me out..if possible any quick session regarding doubts??

Chanti551 commented 1 year ago

And also what types of detections it will detect

Ruud14 commented 1 year ago

I'll try to help you. To start, please show me your config.json file. The detections work based on frame differences. A simplified explanation: If the difference between one frame to the next is significant enough, the recording will start.

mohan51 commented 1 year ago

MicrosoftTeams-image (1)

mohan51 commented 1 year ago

i didn't change anything with the code, i am trying to bringup the actual solution but not able to finding anything

mohan51 commented 1 year ago

i am using arducam uc-698

Ruud14 commented 1 year ago

Your config.json seems correct.

Just for testing, please lower the camera_fps back to 15 and lower the detector_motion_threshold to something really low, like 2, such that it starts recording even when just a tiny bit of motion is detected.

After doing the above, I am curious what your output is. I.e. Are you seeing output starting with Started recording ..? If so, are you also seeing lines starting with ffmpeg version

Chanti551 commented 1 year ago

Hi @Ruud14 I am able to store the detected videos on the server side using recordings_receiver.py..but my only issue is it is happening when both are connected to same network.what we need to do if both are connected to different networks?

Ruud14 commented 1 year ago

Okay, so the recording works now, nice.

I would strongly recommend against using the recordings receiver for sending recordings across networks. Bad actors could connect to the recordings receiver as well and send you any, possibly malicious, file.

If you really want to proceed anyway, you'd need to forward the ports used by the recorings receiver in your router.

To transfer files over the internet I'd recommend using a different means that uses encryption.

Chanti551 commented 1 year ago

Encrypted videos?

Ruud14 commented 1 year ago

No, encrypted communication with propper authentication. (i.e. no one on the internet can see your traffic or impersonate themselves as being you or the camera)

If you forward your port in your router to allow direct traffic from the camera to the receiver, anyone on the internet could, in theory, connect to that receiver and send any file to it. This thus is a major thread and I strongly advise against it.

Ruud14 commented 1 year ago

In short, this SecurityCamera project is not meant to send recordings across the internet and thus I advise you to use some different means for file transfer across the internet.

Chanti551 commented 1 year ago

Then what about streaming.that also we are unable to see when I open the html link in my mobile that connected to different network

Ruud14 commented 1 year ago

Same thing. I'd be insecure to open that up to the internet. Anyone in the world would in theory be able to see your camera feed.

Here again, if you really wanted to, you could setup port forwarding on the router of the network to which the camera is connected to allow http(s) traffic from across the internet to reach your camera feed.

Chanti551 commented 1 year ago

Is it suggested one? I mean port forwarding?

Ruud14 commented 1 year ago

As I said, I advise against it as anyone on the internet could see your camera feed if they go to the specific url.

Chanti551 commented 1 year ago

Can we sort out this with the help of VPN?

Ruud14 commented 1 year ago

I don't think so.

mohan51 commented 1 year ago

Hi @Ruud14 , i am getting like this. it is showing Motion detector is started successfully but no motion is detected, i tried by lowering the fps. MicrosoftTeams-image (2)

mohan51 commented 1 year ago
# Start streaming.
def start(self):
    self._setup_request_handlers()
    try:

        stream_buffer = StreamBuffer(self.camera)
        self.camera.start_recording(stream_buffer, splitter_port=2, **self.h264_args, resize=self.streaming_resolution)

        # Create and loop the tornado application.
        application = tornado.web.Application(self.request_handlers)
        application.listen(self.server_port)
        loop = tornado.ioloop.IOLoop.current()
        stream_buffer.setLoop(loop)
        print("Streamer started on http://{}:{}/index.html".format(self.server_ip, self.server_port))
        asyncio.get_event_loop().run_until_complete(connect_to_websokcet_and_store(self.server_ip,self.server_port))
        loop.start()

    except KeyboardInterrupt:
        self.camera.stop_recording()
        self.camera.close()
        loop.stop()

async def connect_to_websokcet_and_store(ip,port): uri=f"ws://{ip}:{port}/ws/" async with websockets.connect(uri) as websocket: recording_started=False while True: try: data = await websocket.recv() if not recording_started: start_recording() save_data_to_file(data) await asyncio.sleep(60*2) except websockets.exception.ConnectionedClosed: print("Connection closed")

def start_recording(): currenttime = datetime.datetime.now().strftime("%Y-%m-%d%H-%M-%S") filename = f"data_{current_time}.mp4" cmd=["ffmpeg","-y","-analyzeduration","100000000","-probesize","100000000","-f","h264","-i","-",filename] global ffmpeg_process ffmpeg_process=subprocess.Popen(cmd,stdin=subprocess.PIPE)

def save_data_to_file(data): try: ffmpeg_process.stdin.write(data) except BrokenPipeError: print("Broken Pipe")

mohan51 commented 1 year ago

I am trying to modify the streamer.py to store the live data in chunks of duration

getting error like [h264 @ 0x450b010] non-existing PPS 0 referenced Last message repeated 1 times [h264 @ 0x450b010] decode_slice_header error [h264 @ 0x450b010] no frame!

mohan51 commented 1 year ago

@Ruud14 could you please help in this

mohan51 commented 1 year ago

what format of data you are sending to websockets? could you please ping with the line where you are sending data and its format

mohan51 commented 1 year ago

because when we trying to connect websockets from mobile we are unable to decode h264 to bit map

Ruud14 commented 1 year ago

Hi @mohan51.

So you and @Chanti551 are not working together?? Chanti was saying that motion detection was working so this makes things quite confusing.

Please don't comment on other's issues. This, combined with the crippled English, makes things difficult to follow.

I'll try and respond to each comment one by one like this:

Hi @Ruud14 , i am getting like this. it is showing Motion detector is started successfully but no motion is detected, i tried by lowering the fps. MicrosoftTeams-image (2)

Did you try lowering the detector_motion_threshold

# Start streaming.
def start(self):
    self._setup_request_handlers()
    try:

        stream_buffer = StreamBuffer(self.camera)
        self.camera.start_recording(stream_buffer, splitter_port=2, **self.h264_args, resize=self.streaming_resolution)

        # Create and loop the tornado application.
        application = tornado.web.Application(self.request_handlers)
        application.listen(self.server_port)
        loop = tornado.ioloop.IOLoop.current()
        stream_buffer.setLoop(loop)
        print("Streamer started on http://{}:{}/index.html".format(self.server_ip, self.server_port))
        asyncio.get_event_loop().run_until_complete(connect_to_websokcet_and_store(self.server_ip,self.server_port))
        loop.start()

    except KeyboardInterrupt:
        self.camera.stop_recording()
        self.camera.close()
        loop.stop()

async def connect_to_websokcet_and_store(ip,port): uri=f"ws://{ip}:{port}/ws/" async with websockets.connect(uri) as websocket: recording_started=False while True: try: data = await websocket.recv() if not recording_started: start_recording() save_data_to_file(data) await asyncio.sleep(60*2) except websockets.exception.ConnectionedClosed: print("Connection closed")

def start_recording(): currenttime = datetime.datetime.now().strftime("%Y-%m-%d%H-%M-%S") filename = f"data_{current_time}.mp4" cmd=["ffmpeg","-y","-analyzeduration","100000000","-probesize","100000000","-f","h264","-i","-",filename] global ffmpeg_process ffmpeg_process=subprocess.Popen(cmd,stdin=subprocess.PIPE)

def save_data_to_file(data): try: ffmpeg_process.stdin.write(data) except BrokenPipeError: print("Broken Pipe")

Why is this here, half commented half plaintext? Please properly format it, this is not readable.

I am trying to modify the streamer.py to store the live data in chunks of duration

getting error like [h264 @ 0x450b010] non-existing PPS 0 referenced Last message repeated 1 times [h264 @ 0x450b010] decode_slice_header error [h264 @ 0x450b010] no frame!

Please try to get the recorder to work at all before making modifications to it. It does not make sense to start altering the code if the basics are not yet working.

what format of data you are sending to websockets? could you please ping with the line where you are sending data and its format

JMuxer is used for the live video feed together with tornado. (see https://github.com/Ruud14/SecurityCamera/blob/master/web/index.js and https://github.com/Ruud14/SecurityCamera/blob/master/streamer.py)

Chanti551 commented 1 year ago

Hi, I want to know what type of data you are sending through websockets ? Is it h264?

Chanti551 commented 1 year ago

No even though I lowered the detection threshold it is not working properly

Ruud14 commented 1 year ago

Yes it is h264. So you and @mohan51 are one and the same person? Are you working together?

Hi @Ruud14 I am able to store the detected videos on the server side using recordings_receiver.py..but my only issue is it is happening when both are connected to same network.what we need to do if both are connected to different networks?

Here you said that you were able to detect videos right?

Chanti551 commented 1 year ago

Yes me and @mohan51 working together..but initially detection is working only for one instance after finding one detection, the detection functionality is not working

Ruud14 commented 1 year ago

Using the unmodified code and unmodified config try the following:

Modify detector.py and add

print(frame_difference)
print(thresh.sum())

after line

thresh = cv2.threshold(frame_difference, self.motion_threshold, 255, cv2.THRESH_BINARY)[1]

Then look at your console what it outputs. Please send your console output here.

Chanti551 commented 1 year ago

Please have a look into this and suggest if any changes needed https://github.com/Chanti551/Security_camera/blob/Streamer/Streamer_store.py

Ruud14 commented 1 year ago

Please understand that I cannot look through everyones altered version of the project to look for errors. I cannot be everyones personal bug hunter, I am here to deal with issues for this project, and this project only. Not alterations of it.

I can unfortunately only help you if you are using this exact project with no modifications.

The code you referred to is modified and I cannot be the personal problem solver for your code unfortunately.

You are completely free to use and modify this project as you wish though only do this if you know what you're doing and please understand that I cannot help everyone with their alterations of this project.

Chanti551 commented 1 year ago

Ok thank you @Ruud14 one last doubt..what actually the camera is capturing and sending through websockets? Is it same h264 or frames? Or you are using any conversion from frames to h264 and sending through websockets?

Ruud14 commented 1 year ago

Thanks for your understanding. Yes it is h264. You can see the h264 args here (line 20). These args are used to load data into the stream buffer here (line 51). Notice that that line says start_recording which does not mean that it creates a recording file, but it means that it starts putting its frames into the stream buffer. Tornado and JMuxer are then handling the muxing and demuxing of the h264 buffer.

Chanti551 commented 1 year ago

Thank you @Ruud14 , your clarifications regarding the issues I am facing, help me to understand the project clearly..will try to use the functionality at max

Chanti551 commented 1 year ago

Hi @Ruud14 while I had one doubt when raspberrypi is connected to network and we register that camera with http://raspi-ip:8000/index.html in django..but some how if raspberrypi is connected to some other network the IP will change..then how can we address this issue and change the raspi-ip part on django

Ruud14 commented 1 year ago

This is the default behaviour for any device connecting to a network. When a device joins a network, DHCP will assign an IP address to that device. Unless you've specified a specific IP address for that device in the router of that network, the IP address will likely differ each time you connect to the network.

If you have access to the routers of both networks, you can set a static IP address for the Raspberry pi such that its IP address is the same each time you connect to that network.

mohan51 commented 1 year ago

i find a bug in django application whenever we added a camera and want to see the stream from cameras tab,what ever camera we select, it is opening the latest camera stream..suppose if i select camera 1 from 3 camera's. it is showing stream for camera 3

Ruud14 commented 1 year ago

Thanks for reporting. I created an issue for it as you can see.

mohan51 commented 1 year ago

thank you @Ruud14 Ruud

mohan51 commented 1 year ago

Hi @Ruud14 with legacy v3 we can implement client and server separately?

Ruud14 commented 1 year ago

What do you mean with "Implement client and server seperately"? The camera acts as the server to which a user (client) watching the stream connects using their browser. Nothing has to be implemented client side on that regard.

Also, why would you want to use a legacy version instead of the current version?

Chanti551 commented 1 year ago

I think you implemented both client(streamer) and server(web) in the same application..right? Can we separate them to use client and server separately?

Ruud14 commented 1 year ago

What exactly do you refer to as being the client and the server? The camera is the server and your browser is the client.

Chanti551 commented 1 year ago

We are planning to make our application for office use and the manager wants to stream the video through app that his mobile is connected to different network..I saw that your application is creating websocket using the raspberrypi IP address and port.but our thoughts are to create websocket using server IP address ..

Chanti551 commented 1 year ago

And your written storage part on raspberry Pi itself but we are making the storage part on server end(i.e server written separately

Ruud14 commented 1 year ago

I think index.js serves as the server in that regard and the connecting to that server happens here I think. You'd probably be able to run the server on one device and have some code connect to the websocket on the other device. You'd, among other things, need to change the ip address from 8.8.8.8 (local) to the IP address of the other device.