How to import video assets to a Kili project
In this tutorial, we will learn how to import video assets to Kili.
Here are the steps that we will follow:
- Setting up a simple Kili project to work with
- Importing video assets to Kili
- Uploading a video asset using a path to a local file
- Uploading a video asset using an URL
- Uploading a video asset to label each frame separately
- Uploading a list of local images as one video asset
- Uploading a list of image URLs as one video asset
- Uploading a video asset with a custom sampling rate
- Updating video metadata
- Cleanup
Setting up a simple Kili project to work with
Installing and instantiating Kili
First, let's install and import the required modules.
%pip install kili
from kili.client import Kili
Now, let's set up variables needed to create an instance of the Kili object.
We will need your API key and Kili's API endpoint.
If you are unsure how to look up your API key, refer to https://docs.kili-technology.com/docs/creating-an-api-key.
kili = Kili(
# api_endpoint="https://cloud.kili-technology.com/api/label/v2/graphql",
# the line above can be uncommented and changed if you are working with an on-premise version of Kili
)
Creating a basic Kili project
To create a Kili project, you must first set up its interface.
We will create a video project with just one simple classification job and two categories: OBJECT_A
and OBJECT_B
.
To learn more about Kili project interfaces, refer to https://docs.kili-technology.com/docs/customizing-project-interface.
interface = {
"jobs": {
"JOB_0": {
"content": {
"categories": {
"OBJECT_A": {"children": [], "name": "Object A", "id": "category3"},
"OBJECT_B": {"children": [], "name": "Object B", "id": "category4"},
},
"input": "radio",
},
"instruction": "Categories",
"isChild": False,
"mlTask": "CLASSIFICATION",
"models": {},
"isVisible": True,
"required": 1,
"isNew": False,
}
}
}
result = kili.create_project(
title="[Kili SDK Notebook]: Importing Video Assets",
description="Project Description",
input_type="VIDEO",
json_interface=interface,
)
For further processing, we will need to find out what our project ID is.
We can easily retrieve it from the project creation response message:
project_id = result["id"]
print("Project ID: ", project_id)
Project ID: cld90h71d0ha50jptd28xfjg1
Importing video assets to Kili
Now, let's add some video assets to be labeled. You can videos using URLs or use your local assets.
We will use a free off-the-shelf asset from the Internet.
Uploading a video asset using a path to a local file
To show an example of how to upload a local video, we must first download it:
import urllib.request
urllib.request.urlretrieve(
"https://storage.googleapis.com/label-public-staging/asset-test-sample/video/short_video.mp4",
"test.mp4",
)
Now, we can easily upload the video to our project:
assets = kili.append_many_to_dataset(
project_id=project_id, content_array=["./test.mp4"], external_id_array=["video_1_from_local"]
)
Uploading a video asset using an URL
You can of course upload videos using URLs as well. To do so, simply replace './test.mp4'
with the URL of the video that you want to upload.
url = "https://storage.googleapis.com/label-public-staging/asset-test-sample/video/short_video.mp4"
assets = kili.append_many_to_dataset(
project_id=project_id, content_array=[url], external_id_array=["video_2_from_url"]
)
Uploading a video asset to label each frame separately
To upload your video and be able to label frames separately, as individual images, refer to this code:
url = "https://storage.googleapis.com/label-public-staging/asset-test-sample/video/short_video.mp4"
assets = kili.append_many_to_dataset(
project_id=project_id,
content_array=[url],
external_id_array=["video_2_from_url_split_frames"],
json_metadata_array=[{"processingParameters": {"shouldUseNativeVideo": False}}],
)
Uploading a list of local images as one video asset
We can create a video, by using local images as frames. Let's first download some images from the Internet:
urllib.request.urlretrieve(
"https://storage.googleapis.com/label-public-staging/Frame/vid2_frame/video2-img000001.jpg",
"image_1.jpg",
)
urllib.request.urlretrieve(
"https://storage.googleapis.com/label-public-staging/Frame/vid2_frame/video2-img000002.jpg",
"image_2.jpg",
)
urllib.request.urlretrieve(
"https://storage.googleapis.com/label-public-staging/Frame/vid2_frame/video2-img000003.jpg",
"image_3.jpg",
)
Now, let's put them together as one video:
assets = kili.append_many_to_dataset(
project_id=project_id,
json_content_array=[["./image_1.jpg", "./image_2.jpg", "./image_3.jpg"]],
external_id_array=["video_3_from_local_images"],
json_metadata_array=[{"processingParameters": {"shouldUseNativeVideo": False}}],
)
Uploading a list of image URLs as one video asset
You can of course upload videos using URLs as well. To do so, simply replace './test.mp4'
with a set of URLs of images that you want to upload as a video.
url1 = "https://storage.googleapis.com/label-public-staging/Frame/vid2_frame/video2-img000001.jpg"
url2 = "https://storage.googleapis.com/label-public-staging/Frame/vid2_frame/video2-img000002.jpg"
url3 = "https://storage.googleapis.com/label-public-staging/Frame/vid2_frame/video2-img000003.jpg"
assets = kili.append_many_to_dataset(
project_id=project_id,
json_content_array=[[url1, url2, url3]],
external_id_array=["video_4_from_image_urls"],
json_metadata_array=[{"processingParameters": {"shouldUseNativeVideo": False}}],
)
Uploading a video asset with a custom sampling rate
To upload a video with a custom sampling rate (let's say, 10 frames per second), use this code:
assets = kili.append_many_to_dataset(
project_id=project_id,
content_array=["./test.mp4"],
external_id_array=["video_5_custom"],
json_metadata_array=[{"processingParameters": {"framesPlayedPerSecond": 10}}],
)
Updating video metadata
When importing a video, if you want to add or delete metadata, you must provide the entire list of metadata. This new list will replace the previous one, meaning any metadata not included in the new list will be erased. However, this does not apply to the processingParameters
metadata, which will be retained even if they are not present in the new list.
If you need to update processingParameters
keep in mind that you should only do it with caution as it can have an impact on how the video will be managed by the application.
To update a processingParameters
, use this code:
assets = kili.update_properties_in_assets(
project_id=project_id,
external_ids=["video_5_custom"],
json_metadatas=[{"processingParameters": {"framesPlayedPerSecond": 10}}],
)
If you have set custom metadatas to your asset, see here how, and you want to update one property you will have to first get all the json_metadatas and then update the wanted metadata :
updated_json_metadatas = kili.assets(
project_id=project_id, external_id_in=["video_5_custom"], fields=["jsonMetadata"]
)
updated_json_metadatas[0]["jsonMetadata"]["customMetadata"] = 20
assets = kili.update_properties_in_assets(
project_id=project_id,
external_ids=["video_5_custom"],
json_metadatas=[updated_json_metadatas[0]["jsonMetadata"]],
)
Cleanup
We can remove the project that we created:
kili.delete_project(project_id)
Summary
Done. We've successfully set up a video project, defined its interface, and uploaded a bunch of assets to it, using various Kili's upload methods. Well done!