Search code examples
pythonopencvffmpegpyffmpeg

Is it possible to read a Video from POST request into python-ffmpeg or OpenCV?


I've been thinking of a way to read the uploaded Video from POST request with ffmpeg-python or OpenCV so I can process it before saving, so is it possible? And if not, then is it safe to save the video into disk and then do all the processing required? the main point that is bothering me is that I would want to read Video length so I can verify it's valid, so is it also a good idea to save it into disk, check length, and then keep it if its length is in the permitted range, and otherwise I delete it.

Thanks in advance.

Note: I've noticed that the tags don't contain ffmpeg-python, so answers regarding pyffmpeg are also accepted.


Solution

  • After you have received the video you can process it just like any other video in your hard disk . Pay attention to the format of the video. I use video.mp4 in this example.

    import cv2
    video_path="videos/drone-001.mp4"
    
    cap = cv2.VideoCapture(video_path)
    
    # Some characteristics from the original video
    w_frame, h_frame = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps, num_frames = cap.get(cv2.CAP_PROP_FPS), cap.get(cv2.CAP_PROP_FRAME_COUNT)
    
    print(fps,num_frames,w_frame,h_frame)
    
    while(True):
    
        success, frame = cap.read()
        
        if success:
            cv2.imshow('video',frame)
        
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    
    # When everything done, release the capture and destroy windows
    cap.release()
    cv2.destroyAllWindows()
    
    

    Or process the video with ffmpeg ...

    Obtain info about the video:

    ffmpeg -i videos/drone-001.mp4
    
    

    output:

    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'videos/drone-001.mp4':
      Metadata:
        major_brand     : mp42
        minor_version   : 0
        compatible_brands: isommp42
        creation_time   : 2019-12-28T10:01:05.000000Z
      Duration: 00:05:41.38, start: 0.000000, bitrate: 2324 kb/s
        Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 2192 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
        Metadata:
          creation_time   : 2019-12-28T10:01:05.000000Z
          handler_name    : ISO Media file produced by Google Inc. Created on: 12/28/2019.
        Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
        Metadata:
          creation_time   : 2019-12-28T10:01:05.000000Z
          handler_name    : ISO Media file produced by Google Inc. Created on: 12/28/2019.
    

    You can take a look at Flask , WSGI web application framework: https://flask.palletsprojects.com/en/1.1.x/

    and here for file upload configuration and security concern: https://flask.palletsprojects.com/en/1.1.x/patterns/fileuploads/

    LIMIT THE FILE SIZE OF THE VIDEO FILE

    SERVER (or your script that act like a server) do not know the length of the video file ( hours:minutes:seconds) is receving during POST REQUEST from the CLIENT by HTML FORM. But the SERVER can do THREE THINGS TO KNOW THE FILE SIZE in bytes OF the VIDEO FILE.

    First and second are SIMPLE TO HACK because CAN BE FALSIFIED. The third is NOT HACKABLE.

    The first thing is: give full confidence to the user by asking to enter the size of the video file (BAD IDEA).

    The second is: read the HEADER of the HTTP POST REQUEST "content-length: value" (this value can be also falsified by the user).

    The third is: read and count THE NUMBER OF BYTES THE SERVER IS RECEIVING.

    if your BYTE COUNT starts getting TOO HIGH it is a good idea to choose to close the connection.

    So DO THE SCRIPT your self (SOCKET PROGRAMMING) or configure an existing HTTP SERVER or WEB FRAMEWORK to do it for you (i put the link to Flask).

    how does an http post request happen

    When HTML FORM send data , BROWSER make a POST REQUEST sending some information to the server like this:

    This is an example of HTTP HEADER of a POST REQUEST

    POST /video-upload/ HTTP/1.1
    Host: localhost
    User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Content-Type: multipart/form-data; boundary=---------------------------219493771727403213993181042749
    Content-Length: 99211703
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    

    look Content-Length: 99211703

    ... something like 99MB ...

    if the value of content-length is to hight you can abort the connection from server side. Otherwise continue reading and saveing data to the server's hard disk.

    All this stuffs are SOCKET PROGRAMMING.

    You can taste it here: https://realpython.com/python-sockets/

    Ensure Upload Files Cannot Be Executed Rename Files on Upload Validate the Content-Type Header Use a Virus Scanner

    Better for security read the content of the header of the file is uploading becouse HTTP POST HEADER can be totally FALSIFIED .

    here an example for mp4 file format: https://www.file-recovery.com/mp4-signature-format.htm