avfprobe is an OS X command line tool that prints detailed information about audio and video files using AVFoundation.
It loads each file as an AVAsset and decodes and displays information on all of the components, including:
- assets (
AVAsset) - tracks (
AVAssetTrack) - metadata (
AVMetaDataItem) - format descriptions (
CMFormatDescription) - media types (
CMMediaType)
$ avfprobe file ...
Sample output is included for videos from:
- Apple iPhone 5s
- GoPro HERO4 Silver Edition
- ffmpeg output file
Please submit pull requests with sample output from other devices.
The iPhone sample includes an example of a geographic location in the asset metadata:
identifier = "mdta/com.apple.quicktime.location.ISO6709";
keySpace = "mdta";
key = com.apple.quicktime.location.ISO6709;
commonKey = "location";
dataType = "com.apple.metadata.datatype.UTF-8";
value = "+37.4866-122.2296+005.952/";
You can look up "+37.4866-122.2296+005.952/" on Google Maps to see where this video was shot.
It also includes an example of face detection in one of the metadata tracks:
"MetadataKeyDataType" = (NSData *)"com.apple.quicktime.detected-face";
"MetadataKeyValue" = (NSData *)"com.apple.quicktime.detected-face";
"MetadataKeyValue" = (NSData *)"com.apple.quicktime.detected-face.face-id";
"MetadataKeyValue" = (NSData *)"com.apple.quicktime.detected-face.bounds";
"MetadataKeyValue" = (NSData *)"com.apple.quicktime.detected-face.roll-angle";
"MetadataKeyValue" = (NSData *)"com.apple.quicktime.detected-face.yaw-angle";
The GoPro sample includes an example of the camera firmware version in the metadata:
identifier = "uiso/FIRM";
keySpace = "uiso";
key = 1179210317;
commonKey = (null);
dataType = "com.apple.metadata.datatype.raw-data";
value = (NSData *)"HD4.01.02.00.00";
You can look up "HD4.01.02.00.00" on GoPro's website to see that this is a "HERO4 Silver Edition Camera".
avfprobe can also help troublshoot issues, such as this one:
// Temporal Properties
naturalTimeScale = 60000; // {1/60000 = 0.000017} sec
// Frame-Based Characteristics
nominalFrameRate = 59.840160; // fps (= {1002.671082 / 60000} sec/frame)
minFrameDuration = {1001 / 60000 = 0.016683}; // sec (= 59.940060 fps)
Note that the nominalFrameRate for the video track is 59.84 fps, whereas the reciprocal of
minFrameDuration is 59.94 fps. The nominalFrameRate is not commensurate with the track's naturalTimeScale.
The nominalFrameRate corresponds to a frame interval of {3008/180000} whereas minFrameDuration
corresponds to{3003/180000}.
The presentation time stamps of the frames in the track are actually multiples of minFrameDuration
({1001/60000}, {2002/60000}, {3003/60000}, ...).
For some videos, I have found that using the reciprocal of minFrameDuration is more reliable than using nominalFrameRate.