At times you may wish to retrieve media metadata such as duration of a video or the dimensions of an image. For individual video files a website such as probe.video may be sufficient. When requiring this information inside an application or workflow you can use an API such as the Shotstack Media Inspector.
Shotstack's Media Inspector provides you with an API endpoint that fetches the embedded EXIF data and metadata from videos, images and audio.
The probe endpoint, based on ffprobe, queries a video or image for information such as duration, size, dimensions and other helpful information you can use to inform your application.
The output from the endpoint looks like this:
{
"success": true,
"message": "ok",
"response": {
"metadata": {
"streams": [
{
"index": 0,
"codec_name": "h264",
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
"profile": "Main",
"codec_type": "video",
"codec_time_base": "1001/48000",
"codec_tag_string": "avc1",
"codec_tag": "0x31637661",
"width": 1920,
"height": 1080,
"coded_width": 1920,
"coded_height": 1088,
"closed_captions": 0,
"has_b_frames": 1,
"pix_fmt": "yuv420p",
"level": 41,
"color_range": "tv",
"color_space": "bt709",
"color_transfer": "bt709",
"color_primaries": "bt709",
"chroma_location": "left",
"refs": 1,
"is_avc": "true",
"nal_length_size": "4",
"r_frame_rate": "24000/1001",
"avg_frame_rate": "24000/1001",
"time_base": "1/48000",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 1241240,
"duration": "25.859167",
"bit_rate": "10044458",
"bits_per_raw_sample": "8",
"nb_frames": "620",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0
},
"tags": {
"language": "eng",
"handler_name": "VideoHandler"
}
},
{
"index": 1,
"codec_name": "aac",
"codec_long_name": "AAC (Advanced Audio Coding)",
"profile": "LC",
"codec_type": "audio",
"codec_time_base": "1/48000",
"codec_tag_string": "mp4a",
"codec_tag": "0x6134706d",
"sample_fmt": "fltp",
"sample_rate": "48000",
"channels": 2,
"channel_layout": "stereo",
"bits_per_sample": 0,
"r_frame_rate": "0/0",
"avg_frame_rate": "0/0",
"time_base": "1/48000",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 1242096,
"duration": "25.877000",
"bit_rate": "317375",
"max_bit_rate": "317375",
"nb_frames": "1215",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0
},
"tags": {
"language": "eng",
"handler_name": "SoundHandler"
}
}
],
"chapters": [],
"format": {
"filename": "https://github.com/shotstack/test-media/raw/main/captioning/scott-ko.mp4",
"nb_streams": 2,
"nb_programs": 0,
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"format_long_name": "QuickTime / MOV",
"start_time": "0.000000",
"duration": "25.920000",
"size": "33513207",
"bit_rate": "10343582",
"probe_score": 100,
"tags": {
"major_brand": "isom",
"minor_version": "512",
"compatible_brands": "isomiso2avc1mp41",
"encoder": "Hybrik 1.215.18"
}
}
}
}
}
You can use the probe endpoint by sending a GET request to https://api.shotstack.io/v1/probe
, and add the url of the file you'd like to inspect as an encoded url. Most popular languages will have built-in methods that allow you to encode URLs such as JavaScript's encodeURIComponent().
For example, the url:
https://shotstack-assets.s3.amazonaws.com/footage/night-sky.mp4
becomes:
https%3A%2F%2Fshotstack-assets.s3.amazonaws.com%2Ffootage%2Fnight-sky.mp4
which can be used in your GET request:
curl --request GET 'https://api.shotstack.io/v1/probe/https%3A%2F%2Fshotstack-assets.s3.amazonaws.com%2Ffootage%2Fnight-sky.mp4'
There are two common use cases for the Media Inspector:
In this example we will combine the following three video files:
By using the probe endpoint we can identify the duration of each of these videos:
curl --request GET 'https://api.shotstack.io/v1/probe/https%3A%2F%2Fshotstack-assets.s3.amazonaws.com%2Ffootage%2Fdesert-overhead.mp4'
curl --request GET 'https://api.shotstack.io/v1/probe/https%3A%2F%2Fshotstack-assets.s3.amazonaws.com%2Ffootage%2Fdrone-car-overhead.mp4'
curl --request GET 'https://api.shotstack.io/v1/probe/https%3A%2F%2Fshotstack-assets.s3.amazonaws.com%2Ffootage%2Fbeach-overhead.mp4'
These commands should give you the details of those three video assets, similar to the following:
{
"response": {
"metadata": {
...,
"streams": [
{
...,
"duration": "13.04",
...
}
]
}
}
}
With the other two video being 12.812800
seconds and 31.593333
seconds, respectively.
With this information we can now create our merged video:
{
"timeline": {
"tracks": [
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/desert-overhead.mp4"
},
"start": 0,
"length": 13.04
}
]
},
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/drone-car-overhead.mp4"
},
"start": 13.04,
"length": 12.81
}
]
},
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/beach-overhead.mp4"
},
"start": 12.81,
"length": 31.59
}
]
}
]
},
"output": {
"format": "mp4",
"resolution": "hd"
}
}
In this second example we want to make sure every image we use in our video is 250px wide. We can use the scale property to resize the image to exactly these dimensions.
Firstly we want to scale the following image:
We fetch the metadata of the image using:
curl --request GET 'https://api.shotstack.io/v1/probe/https%3A%2F%2Fshotstack-assets.s3-ap-southeast-2.amazonaws.com%2Fimages%2Fbusiness-man.jpg'
{
"response": {
"metadata": {
"streams": [
{
...,
"width": 640,
"height": 640,
...
}
],
...
}
}
}
For this image, in order to get our image to scale to 250px we set the scale property to 0.39 (250px / 640px):
{
"timeline": {
"tracks": [
{
"clips": [
{
"asset": {
"type": "image",
"src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/images/business-man.jpg"
},
"start": 0,
"length": 10,
"fit": "none",
"scale": 0.39
}
]
}
]
},
"output": {
"format": "mp4",
"resolution": "sd"
}
}
Let's do this again with the following image:
To view the image metadata of the new image:
curl --request GET 'https://api.shotstack.io/v1/probe/https%3A%2F%2Fshotstack-assets.s3.amazonaws.com%2Fimages%2Freal-estate-agent-male.jpg'
{
"response": {
"metadata": {
"streams": [
{
...,
"width": 400,
"height": 400,
...
}
],
...
}
}
}
For this image, in order to get our image to scale to 250px we set the scale property to 0.625 (250px / 400px):
{
"timeline": {
"tracks": [
{
"clips": [
{
"asset": {
"type": "image",
"src": "https://shotstack-assets.s3.amazonaws.com/images/real-estate-agent-male.jpg"
},
"start": 0,
"length": 10,
"fit": "none",
"scale": 0.625
}
]
}
]
},
"output": {
"format": "mp4",
"resolution": "sd"
}
}
curl --request POST 'https://api.shotstack.io/v1/render' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
"timeline": {
"tracks": [
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/beach-overhead.mp4"
},
"start": 0,
"length": "auto"
}
]
}
]
},
"output": {
"format": "mp4",
"size": {
"width": 1280,
"height": 720
}
}
}'