简体   繁体   中英

How to check whether a given file is a valid video file in C++?

I tried to do it using OpenCV:

std::string input_name = "<path to file>";
cv::VideoCapture cap(input_name);
if(!cap.isOpened()) printf("Invalid video\n");

However, when I try passing a .txt file, VideoCapture reads it successfully for unknown reasons. When I try to find the number of frames in the video,

if(cap.get(cv::CV_CAP_PROP_FRAME_COUNT) == 0) printf("Invalid video\n");

I get a different number of frames each time I execute. I also tried finding the width and height of a frame in the file,

cv::Mat Frame;
if(!cap.read(Frame)) printf("Cannot read frame\n");
else
{
    printf("Frame width is %d\n", Frame.cols);
    printf("Frame height is %d\n", Frame.rows);
}

their values are 640 and 400 respectively. Why is this happening? Is there a way to check if a given file is a valid video file preferably using OpenCV?

The only really good way to determine if a file is "valid", is to read its content with an appropriate reader-function that understands that very format. There is no simple, universal marker to say "this is a genuine video file, and can't be something else" - and even if there was, someone could on purpose or by mistake put that in the file so that it looks like a "real video", but isn't when you read the rest of the information. Since there are dozens of different video file formats, it's hard to do something more sensible than "try it, see what happens".

As discussed in another answer, cv::VideoCapture::read() will read the file and return an error indication if the file is not valid. If you want to distinguish between "file doesn't exist", you could do some checking before you try to read it, so you can say "file doesn't exist" as opposed to "sorry, but it seems like that's not a valid video file" - although the latter does apply to "there is no such file" too.

Note that I expect cv::VideoCapture to say isOpened() if the file exists, so for a text-file or PDF, it will happily accept that as "opened". You have to actually try to READ the file to tell if it's a video file. However, the documentation for both ::get and ::read is pretty useless in respect of "What happens on bad input", it almost seems like the functions are designed to only work with valid input.

I'm not familiar with openCV but you can always check for file extension.

kdt wrote a method for this in this question https://stackoverflow.com/a/874160/4612406

bool hasEnding (std::string const &fullString, std::string const &ending) 
{
    if (fullString.length() >= ending.length()) {
        return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
    } else {
        return false;
    }
}

Just pass the name of the file and the file extension you want like ".mp4". You can change this method to take vector for ending string and check for every string in the vector where you can place .mp4 .avi etc.

you can use the method VideoCapture::read() , that will return false if:

  • the video is corrupt
  • the string path is pointing to an invalid file

example:

cv::VideoCapture cap(input_name);
auto x = cap.read(im);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM