I am trying to open a video and using python get a frame array with frame by frame for post-processing.
I am in android termux, I have ffmpeg and opencv2 installed with python3.
When I try to open the video with
import cv2
import numpy as np
# create VideoCapture object
cap = cv2.VideoCapture('video.mp4')
if (cap.isOpened() == False):
print('Error while trying to open video. Please check again...')
I alway get the print error. 'Error while trying to open video. Please check again...'. cap.isOpened() is false, I don't get any exception. I have read online that on android opencv it will only read from an mpeg avi.
I tried using ffmpeg to transform video.mp4 to video.avi but it still fails. I tried a bunch of ffmpeg command none worked so far.
Any ffmpeg command that could convert my video into something readable for opencv on android? Or some code to load the video frames into an array frames[]= ... using ffmpeg-python or subprocess pipe with ffmpeg?
List of ffmpeg command used
ffmpeg -i video.mp4 -vcodec mjpeg output.mjpeg
ffmpeg -i output.mjpeg -vcodec output.avi
ffmpeg -i output.mjpeg -vcodec mjpeg output.avi
ffmpeg -i video.mp4 video.avi
ffmpeg -i video.mp4 -vcodec mjpeg out.avi
Ffmpeg -i video.mp4 output
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.83.100
Duration: 00:02:42.34, start: 0.000000, bitrate: 4705 kb/s
Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, smpte170m/bt470bg/smpte170m, progressive), 1280x608, 4570 kb/s, 30.01 fps, 30 tbr, 1000k tbn (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
CodePudding user response:
I ended up using ffmpeg instead of opencv. Turns out opencv can't handle vfr mp4 on android and it only supports a very limited set of .avi.
I was able to use a ffmpeg filter and re-encode the video to a cfr.
I used a 2 pass transformation to make it a constant 30fps video.
ffmpeg -i pvp2.mp4 -vsync cfr pvp2cfr2.mp4
ffmpeg -i pvp2cfr2.mp4 -filter:v fps=30 pvp2cfr30.mp4