0

Im using uv4l to stream from my raspberry pi, and it works perfectly but if i wanna use a python script to record while streaming i'm getting this error:

mmal: mmal_vc_port_enable: failed to enable port vc.null_sink:in:0(OPQV): ENOSPC
mmal: mmal_port_enable: failed to enable connected port (vc.null_sink:in:0(OPQV))0x24a6300 (ENOSPC)
mmal: mmal_connection_enable: output port couldn't be enabled
Traceback (most recent call last):
  File "app.py", line 3, in <module>
    camera = picamera.PiCamera()
  File "/usr/lib/python3/dist-packages/picamera/camera.py", line 433, in __init__
    self._init_preview()
  File "/usr/lib/python3/dist-packages/picamera/camera.py", line 513, in _init_preview
    self, self._camera.outputs[self.CAMERA_PREVIEW_PORT])
  File "/usr/lib/python3/dist-packages/picamera/renderers.py", line 558, in __init__
    self.renderer.inputs[0].connect(source).enable()
  File "/usr/lib/python3/dist-packages/picamera/mmalobj.py", line 2212, in enable
    prefix="Failed to enable connection")
  File "/usr/lib/python3/dist-packages/picamera/exc.py", line 184, in mmal_check
    raise PiCameraMMALError(status, prefix)
picamera.exc.PiCameraMMALError: Failed to enable connection: Out of resources

My guess is that two process can't use the same resource in this case the camera, so that leave me with the question: is there a way to do this with python? the thing i'm building a security system and using python and i'm trying to record video when you detect a person but i should be able to still stream the video while the system is recording it.

this is my code for recording video right now that i'm testing

import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.start_recording('my_video.h264')
    camera.wait_recording(6)
    camera.stop_recording()

as you can see is a simple recording method to run on python3 i need to at least fetch the streaming and save it. But it seems imposible the most close i've found on internet is how to take a screenshot with an opencv code but not saving video.

2 Answers 2

0

just use python script as a wrapper to embed a ffmpeg / avconv capture command .. this is much more easy and works fine... assuming you're using uv4l-server :

generate a stream capture of your device /dev/videoX -> uv4l-raspicam driver -> uv4-server:port

launch a service that calls a python script using process.call with :

 avconv/ffmpeg -i http://uv4lserver_address:uv4l_port/stream/video.mjpeg or(x264) -vf  /your_output_dir/filename.videoformat
3
  • I'm trying this but it shows only an image for the time i spend recording it seems it's not refreshing ffmpeg -r 30 -i 127.0.0.1:8080/stream/video.mjpeg try.avi -y Feb 14, 2018 at 18:16
  • I actually success to open the video with omxplay but i need to open it with vlc Feb 14, 2018 at 18:20
  • did you try .flv output format to be read by vlc ? Feb 16, 2018 at 11:12
0

Yes as i thought the problem is that two different process can't use the same camera, but what i did was to use the streaming address and record it in to a file and send it to my server. Here is my code:

import requests
import time
import subprocess
import os.path
import pathlib
import base64
from API import ApiComunicacion

class Camera():

    def __init__(self,recording):
        self.recording = recording
        self.api = ApiComunicacion()

    def record_video(self):
        print('Recording')
        url = 'http://127.0.0.1:8080/stream/video.mjpeg'
        local_filename = url.split('/')[-1]
        # NOTE the stream=True parameter
        r = requests.get(url, stream=True)

        filename = time.strftime("%Y%m%d-%H%M%S")+'.mp4'
        save_path = '/home/pi/Downloads/tesis/video'
        completed_video= os.path.join(save_path, filename)

        i=0
        with open(completed_video, 'wb') as f:
            for chunk in r.iter_content(chunk_size=1024): 
                if chunk: # filter out keep-alive new chunks
                    f.write(chunk)
                    i = i + 1
                    #f.flush() commented by recommendation from J.F.Sebastian
                    if(self.recording == False or i==10000):
                        print('Sending')
                        f.close()
                        with open(completed_video,'rb') as f:
                            video = f.read()
                            encode_video = base64.encodebytes(video)

                            json = {'ip_address': '10.10.10.110',
                                    'date': time.strftime('%Y-%m-%d %H:%M:%S'),
                                    'video': encode_video}

                            r = self.api.post(json,'createvideo')
                            a = r.json()
                            print(a)
                            path = pathlib.Path(completed_video)
                            path.unlink()
                            f.close()
                            break
        return local_filename

    def recording(self):
        self.recording = not self.recording

camera = Camera(True)

camera.record_video()

so in other words i'm not using the camera two times i'm recording from the streaming of UV4L and then to send it to my server i encode the video with base 64 and send it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.