pythonopencvvideo-encodingmkv

How to read MKV bytes as video?


I am receiving fragment of MKV video in bytes. I need to take 1st frame of it for later processing without saving video in disk. For similar problem with image I use OpenCV or PIL and everything works fine, however, I am not able to do the same with video data. Any tips how to read video from bytes to memory object that I could use for later processing with OpenCV or some other library?


Solution

  • As I don't have your bytes buffer, I just created an MKV video file with ffmpeg like this:

    ffmpeg -i SomeVideo.avi -f matroska -vcodec libx264 video.mkv
    

    I then installed imageio with:

    pip install imageio
    

    Then I loaded the entire MKV video into memory so I have something that must look pretty much the same as the bytes object you receive stored in my variable content:

    import imageio
    
    # Get bytes of MKV video
    with open('video.mkv', 'rb') as file: 
        content = file.read()
    

    Now I should be set up and looking the same as you. Just for reference, the first few bytes of content look like this:

    b'\x1aE\xdf\xa3\x01\x00\x00\x00\x00\x00\x00#B\x86\x81\x01B\xf7\x81\x01'
    

    So, let's continue.

    # Wrap the content in a BytesIO and get an ffmpeg reader to read it 
    vid = imageio.get_reader(BytesIO(content),  'ffmpeg')
    

    I can now print the mean of each frame like this:

    for num, image in enumerate(vid.iter_data()): 
        print(image.mean())
    

    Or get the metadata and print it like this:

    metadata = vid.get_meta_data()                                                             
    
    print(metadata)
    
    {'plugin': 'ffmpeg',
     'nframes': 750,
     'ffmpeg_version': '4.1 built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)',
     'fps': 25.0,
     'source_size': (1280, 720),
     'size': (1280, 720),
     'duration': 30.0}
    

    Keywords: Python, video, frame, individual frame, FFmpeg, imageio, single frame, BytesIO, bytes, MKV, Matroska.