6

I'm writing a Windows application in Python which has to read metadata from an .MP4 video file.

I started writing the application in Python 3, but was unable to find a suitable module to read metadata from video files. That's when I used 3to2 to move the entire project to Python 2, so I could install Hachoir-Metadata, which was praised all over the net, using pip install hachoir-core, pip install hachoir-parser, and pip install hachoir-metadata

I used the following code:

from hachoir_core.error import HachoirError
from hachoir_core.cmd_line import unicodeFilename
from hachoir_parser import createParser
from hachoir_core.tools import makePrintable
from hachoir_metadata import extractMetadata
from hachoir_core.i18n import getTerminalCharset

# Get metadata for video file
def metadata_for(filename):

    filename, realname = unicodeFilename(filename), filename
    parser = createParser(filename, realname)
    if not parser:
        print "Unable to parse file"
        exit(1)
    try:
        metadata = extractMetadata(parser)
    except HachoirError, err:
        print "Metadata extraction error: %s" % unicode(err)
        metadata = None
    if not metadata:
        print "Unable to extract metadata"
        exit(1)

    text = metadata.exportPlaintext()
    charset = getTerminalCharset()
    for line in text:
        print makePrintable(line, charset)

    return metadata

pathname = c:/video.mp4
meta = metadata_for(pathname)
print meta

This returned the following metadata:

  • Duration: 37 sec 940 ms
  • Image width: 1280 pixels
  • Image height: 960 pixels
  • Creation date: 2014-12-13 19:27:36
  • Last modification: 2014-12-13 19:27:36
  • Comment: Play speed: 100.0%
  • Comment: User volume: 100.0%
  • MIME type: video/quicktime
  • Endianness: Big endian

This is great, except for the fact that I also really need to know the frames per second (FPS).. For .AVI files Hachoir-Metadata does show the FPS, as you can see from this test output:

  • Duration: 6 sec 66 ms
  • Image width: 256 pixels
  • Image height: 240 pixels
  • Frame rate: 30.0 fps
  • Bit rate: 884.4 Kbit/sec
  • Comment: Has audio/video index (2920 bytes)
  • MIME type: video/x-msvideo
  • Endianness: Little endian

And yes, the FPS tag is set on the .MP4 file (100fps).

Is there a way to extract the FPS from a .MP4 file? Preferably including width(px), height(px), duration, and creation time as well.

Thanks in advance for any help!

kregus
  • 1,003
  • 10
  • 18
  • The data that you have shown dose include all the information that you requested __but__ 100 fps sounds _unlikely_ for a video file - MP4/quicktime does not truly have a frame rate as it uses keyframes and interpolation frames I suspect that whatever is reporting `100 fps` is incorrectly labeling the `Play Speed=100%` and Hachoir is correct. – Steve Barnes Jan 09 '15 at 06:08
  • @SteveBarnes Thanks for your quick answer! The video was shot using a GoPro HERO3 Black edition, which is capable of shooting 100 fps. Windows explorer > file properties > details tab also shows the 100 fps. – kregus Jan 09 '15 at 08:42
  • Glad you got is sorted @kregus – Steve Barnes Jan 09 '15 at 18:40
  • can `metadata_for ` method take file instead of filepath ? – Nitesh Verma May 16 '18 at 09:25

2 Answers2

4

Ok, I managed to extract all the data I need and more! This answer on Stack Overflow gave me the idea to try MediaInfo to extract metadata.

For this I switched back to Python 3 again. I also had to change line 22 in MediaInfoDLL3.py to MediaInfoDLL_Handler = WinDLL("C:\Program Files (x86)\MediaInfo\MediaInfo_i386.dll")

This is the code I used:

import os

os.chdir(os.environ["PROGRAMFILES"] + "\\mediainfo")  # The folder where you installed MediaInfo
from MediaInfoDLL3 import MediaInfo, Stream

MI = MediaInfo()

def get_mediainfo_from(directory):
  for file in os.listdir(directory):
    MI.Open(directory + file)
    file_extension = MI.Get(Stream.General, 0, "FileExtension")
    duration_string = MI.Get(Stream.Video, 0, "Duration/String3")  # Length. "Duration" for ms
    fps_string = MI.Get(Stream.Video, 0, "FrameRate")
    width_string = MI.Get(Stream.Video, 0, "Width")
    height_string = MI.Get(Stream.Video, 0, "Height")
    aspect_ratio_string = MI.Get(Stream.Video, 0, "DisplayAspectRatio")
    frames_string = MI.Get(Stream.Video, 0, "FrameCount")
    local_created_date_string = MI.Get(Stream.General, 0, "File_Created_Date_Local")  # Date of copying
    local_modified_date_string = MI.Get(Stream.General, 0, "File_Modified_Date_Local")  # Date of filming

    if file_extension == "MP4":
      print("Extension: "+file_extension)
      print("Length: "+duration_string)
      print("FPS: "+fps_string)
      print("Width: "+width_string)
      print("Height: "+height_string)
      print("Ratio: "+aspect_ratio_string)
      print("Frames: "+frames_string)
      print("Created Date: "+local_created_date_string)
      print("Modified Date: "+local_modified_date_string)

    else:
      print("{} ain't no MP4 file!".format(file))

    MI.Close()

get_mediainfo_from("C:\\Users\\Nick\\Desktop\\test\\")  # The folder with video files

# print(MI.Option("Info_Parameters"))  # Show list of available metadata tags

This returned:

  • Extension: MP4
  • Length: 00:00:37.940
  • FPS: 100.000
  • Width: 1280
  • Height: 960
  • Ratio: 1.333
  • Frames: 3794
  • Created Date: 2015-01-07 15:25:11.678
  • Modified Date: 2014-12-13 19:28:14.000

Hopefully this helps someone!

Community
  • 1
  • 1
kregus
  • 1,003
  • 10
  • 18
1

This is totally different from the way you have approached with the problem. I wanted to get only the fps of a mp4 video and I got it by using openCV. This is not an answer but I thought it will be useful for someone.

import cv2
cap = cv2.VideoCapture('name_of_video_file')
fps    = cap.get(cv2.CAP_PROP_FPS)
print 'fps=',fps

You can get other metadata also in the same way. For eg.,

length_of_video = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
width  = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

This site will help you with the keywords: http://docs.opencv.org/3.1.0/dd/de7/group__videoio.html

Arun Sooraj
  • 737
  • 9
  • 20