pythonopencvvideocodecvideo-compression

Video created with OpenCV python cannot be uploaded to Social Media Platforms


I use OpenCV in a python script to convert images in PIL format to MP4 videos.

Even though I can play back the videos normally after creating them, I cannot upload them on Twitter or Instagram afterwards.

If after creating the video, I convert the created MP4 video, with an external video converter, to the same MP4 video format, it can now be uploaded to both Twitter and instagram. So the issue must be somehow related to the coding formatting of openCV.

I tried using different codec formats instead of 'mp4v', any fourcc encoding format I found online that is compatible with MP4 videos, but the issue remained.

What else could I try to change in the export settings, to hopefully be able to directly upload videos created with openCV?

Here's the sample code I use:

import cv2
import numpy as np
from PIL import Image as Img

#Create a list of PIL images:
PILimages = []
for  i in range(20):
    digit = str(i)
    if i < 10:
        digit = "0" + digit 
    image = Img.open("animationframes/frame " + digit + ".png")
    PILimages.append(image)

#Convert the PIL image list to OpenCV format: 
def PILimageGroupToOpenCV(imageGroup):
    openCVimages = []
    for image in imageGroup:    
        opencvImage_ = np.asarray(image)
        opencvImage_ = cv2.cvtColor(opencvImage_, cv2.COLOR_RGB2BGR)
        openCVimages.append(opencvImage_)
    return openCVimages

#Save the frames as an MP4 video using openCV:
def SavePILimagesToMp4(images,PathAndName,FPS):
    #Convert the PIL images to numpy and then to OpenCV:
    openCVimages = PILimageGroupToOpenCV(images)
    #Create the new video:
    height,width, layers = openCVimages[0].shape
    size = (width,height)
    video = cv2.VideoWriter(PathAndName, cv2.VideoWriter_fourcc(*'mp4v'), FPS, size)
    #Add the images as frames into the video:
    for i in range(len(openCVimages)):
        video.write(openCVimages[i])
    video.release()

#Save the pil images:
SavePILimagesToMp4(PILimages,"out.MP4",25)

Solution

  • "mp4v" represents H.263, MPEG 4 ASP. You might have heard of DivX and XviD. That is that.

    Your target sites seem to reject that video format.

    If you want H.264, MPEG 4 AVC, you need to ask for "avc1" instead. You can also try asking for "VP80".

    OpenCV usually comes with ffmpeg, but that ffmpeg often does not come with an encoder for H.264.

    It might support OpenH264, which is provided by Cisco on their Github. You can download the DLL for that. Make sure it's the exact version that OpenCV asks for when it fails to find the DLL.

    Failed to load OpenH264 library: openh264-1.8.0-win64.dll
            Please check environment and/or download library: https://github.com/cisco/openh264/releases
    
    [libopenh264 @ 0000018c889e9c40] Incorrect library version loaded
    [ERROR:0@0.040] global cap_ffmpeg_impl.hpp:3049 open Could not open codec libopenh264, error: Unspecified error (-22)
    [ERROR:0@0.040] global cap_ffmpeg_impl.hpp:3066 open VIDEOIO/FFMPEG: Failed to initialize VideoWriter
    

    You need to make sure the DLL is in a place where it can be found. On Windows, there is a defined algorithm for finding DLLs. Do not place it where it doesn't belong. It does not belong in the system32 directory.

    In my experiments, I could place the DLL in the current working directory and it was picked up. It's also supposed to be picked up when it's in the same directory as the executable for the current process (the python process).