How to Use Katna.video

Extract keyframes for a video

Step 1

Import the video module

from Katna.video import Video

Step 2

Instantiate the video class inside your main module (necessary for multiprocessing in windows)

if __name__ == "__main__":
     vd = Video()

Step 3

Call the extract_video_keyframes method. The method accepts two parameters and returns a list of numpy 2D array which are images. Refer to API reference for further details. Below are the two parameters required by the method

  1. no_of_frames: Number of key frames to be extracted
  2. file_path: Video file path.
imgs = vd.extract_video_keyframes(no_of_frames = no_of_frames_to_return, \
file_path= video_file_path)

Step 4 (Optional)

In case you want to persist the extracted key frames then call the save_frame_to_disk method. The method accepts three parameters and returns nothing. Refer to API reference for further details. Below are the two parameters required by the method

  1. frame: In-menory images generated by extract_video_keyframes method.
  2. file_name: File name pattern for the persisted image.
  3. file_path: Folder location where files needs to be saved
  4. file_ext: File extension indicating the file type for example - ‘.jpg’
vd.save_frame_to_disk(img, file_path=output_folder_video_image, \
     file_name="test_"+str(counter), file_ext=".jpeg")

Code below is a complete example for a single video file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from Katna.video import Video
import os

# For windows, the below if condition is must.
if __name__ == "__main__":

  #instantiate the video class
  vd = Video()

  #number of key-frame images to be extracted
  no_of_frames_to_return = 12

  #Input Video file path
  video_file_path = os.path.join(".", "tests","data", "pos_video.mp4")

  #Call the public key-frame extraction method
  imgs = vd.extract_video_keyframes(no_of_frames = no_of_frames_to_return, \
       file_path= video_file_path)

  # Make folder for saving frames
  output_folder_video_image = 'selectedframes'
  if not os.path.isdir(os.path.join(".", output_folder_video_image)):
       os.mkdir(os.path.join(".", output_folder_video_image))

  # Save all frames to disk
  for counter,img in enumerate(imgs):
       vd.save_frame_to_disk(img, file_path=output_folder_video_image, \
            file_name="test_"+str(counter), file_ext=".jpeg")

Extract keyframes for all videos in a directory

Call the extract_keyframes_from_videos_dir method. The method accepts two parameters and return a dictionary with the file path as the key and list of numpy 2D array (which are images) as its value.

  1. no_of_frames: Number of key frames to be extracted
  2. dir_path: Directory path which has all the videos.
imgs = vd.extract_keyframes_from_videos_dir(no_of_frames = no_of_frames_to_return, \
dir_path= dir_path_containing_videos)

Code below is a complete example for a directory containing videos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from Katna.video import Video
import os
import ntpath

# For windows, the below if condition is must.
if __name__ == "__main__":

  #instantiate the video class
  vd = Video()

  #number of key-frame images to be extracted
  no_of_frames_to_return = 3

  #Input Video directory path
  #All .mp4 and .mov files inside this directory will be used for keyframe extraction)
  videos_dir_path = os.path.join(".", "tests","data")

  #Call the public key-frame extraction method
  imgs = vd.extract_keyframes_from_videos_dir(no_of_frames = no_of_frames_to_return, \
       dir_path = videos_dir_path)

  # Make folder for saving frames
  output_folder_video_image = 'selectedframes'
  if not os.path.isdir(os.path.join(".", output_folder_video_image)):
       os.mkdir(os.path.join(".", output_folder_video_image))

  # Save all the frames to disk by segregating them into folders having the same name as the video file
  for filepath, keyframe_data_li in imgs.items():

       # name of the video file
       filename = ntpath.basename(filepath)
       name = filename.split(".")[0]

       # folder path where the images will be stored
       output_file_parent_folder_path = os.path.join(".", output_folder_video_image, name)

       # make folder with name of video if it doesnt exist
       if not os.path.exists(output_file_parent_folder_path):
            os.makedirs(output_file_parent_folder_path)

       # save keyframes inside the folder
       for counter, img in enumerate(keyframe_data_li):
            vd.save_frame_to_disk(img, file_path=output_file_parent_folder_path,
                 file_name=name + "_" + str(counter), file_ext=".jpeg")

Compress video using Katna

Step 1

Import the video module

from Katna.video import Video

Step 2

Instantiate the video class inside your main module (necessary for multiprocessing in windows)

if __name__ == "__main__":
     vd = Video()

Step 3

Call the compress_video method. The method accepts one required parameter that is path to input file returns status whether compression was done successfully or not. Refer to API reference for further details. Below are the parameters required by the method

  1. file_path: Input video full file path. This is the only compulsory parameter
status = vd.compress_video(file_path= video_file_path)

Step 4 (Optional)

In case you play around with the different parameters like where to save compressed file etc. you can change optional parameters in compress_video function. Refer to API reference for further details. Below are the optional parameters supported by the method

1. force_overwrite (bool, optional) – optional parameter if True then if there is already a file in output file location function will overwrite it, defaults to False

2. crf_parameter (int, optional) – Constant Rate Factor Parameter for controlling amount of video compression to be applied, The range of the quantizer scale is 0-51: where 0 is lossless, 23 is default, and 51 is worst possible. It is recommend to keep this value between 20 to 30 A lower value is a higher quality, you can change default value by changing config.Video.video_compression_crf_parameter

3. output_video_codec (str, optional) – Type of video codec to choose, Currently supported options are libx264 and libx265, libx264 is default option. libx264 is more widely supported on different operating systems and platforms, libx265 uses more advanced x265 codec and results in better compression and even less output video sizes with same or better quality. Right now libx265 is not as widely compatible on older versions of MacOS and Widows by default. If wider video compatibility is your goal you should use libx264., you can change default value by changing Katna.config.Video.video_compression_codec

4. out_dir_path (str, optional) – output folder path where you want output video to be saved, defaults to “”

5. out_file_name (str, optional) – output filename, if not mentioned it will be same as input filename, defaults to “”

vd.compress_video(file_path, force_overwrite=False, \
crf_parameter=23, output_video_codec='libx264', out_dir_path='', out_file_name='')

Code below is a complete example for a single video file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  import os
  from Katna.video import Video

  def main():

       vd = Video()

       # folder to save extracted images
       output_folder_for_compressed_videos= "compressed_folder"
       out_dir_path = os.path.join(".", output_folder_for_compressed_videos)

       if not os.path.isdir(out_dir_path):
            os.mkdir(out_dir_path)

       # Video file path
       video_file_path = os.path.join(".", "tests", "data", "pos_video.mp4")
       print(f"Input video file path = {video_file_path}")

       status = vd.compress_video(
            file_path=video_file_path,
            out_dir_path=out_dir_path
       )


  if __name__ == "__main__":
       main()

Compress all videos in folder using Katna

Step 1

Import the video module

from Katna.video import Video

Step 2

Instantiate the video class inside your main module (necessary for multiprocessing in windows)

if __name__ == "__main__":
     vd = Video()

Step 3

Call the compress_videos_from_dir method. The method accepts one required parameter that is path to input folder where videos needs to be picked for compression returns status whether compression was done successfully or not. Refer to API reference for further details. Below are the parameters required by the method

  1. dir_path: Input videos full folder path. This is the only compulsory parameter
status = vd.compress_videos_from_dir(dir_path=input_video_folder_path)

Step 4 (Optional)

In case you play around with the different parameters like where to save compressed file etc. you can change optional parameters in compress_video function. Refer to API reference for further details. Below are the optional parameters supported by the method

1. force_overwrite (bool, optional) – optional parameter if True then if there is already a file in output file location function will overwrite it, defaults to False

2. crf_parameter (int, optional) – Constant Rate Factor Parameter for controlling amount of video compression to be applied, The range of the quantizer scale is 0-51: where 0 is lossless, 23 is default, and 51 is worst possible. It is recommend to keep this value between 20 to 30 A lower value is a higher quality, you can change default value by changing config.Video.video_compression_crf_parameter

3. output_video_codec (str, optional) – Type of video codec to choose, Currently supported options are libx264 and libx265, libx264 is default option. libx264 is more widely supported on different operating systems and platforms, libx265 uses more advanced x265 codec and results in better compression and even less output video sizes with same or better quality. Right now libx265 is not as widely compatible on older versions of MacOS and Widows by default. If wider video compatibility is your goal you should use libx264., you can change default value by changing Katna.config.Video.video_compression_codec

4. out_dir_path (str, optional) – output folder path where you want output video to be saved, defaults to “”

vd.compress_videos_from_dir(dir_path, force_overwrite=False, \
crf_parameter=23, output_video_codec='libx264', out_dir_path='')

Code below is a complete example for a single video file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  import os
  from Katna.video import Video

  def main():

       vd = Video()

       # folder to save extracted images
       output_folder_for_compressed_videos= "compressed_folder"
       out_dir_path = os.path.join(".", output_folder_for_compressed_videos)

       if not os.path.isdir(out_dir_path):
            os.mkdir(out_dir_path)

       # Video file path
       video_folder_path = os.path.join(".", "tests", "data")
       print(f"Input video folder path = {video_folder_path}")

       status = vd.compress_videos_from_dir(
            dir_path=video_folder_path,
            out_dir_path=out_dir_path
       )


  if __name__ == "__main__":
       main()

Smart video resize using katna

Please note that is it necessary to first install and initialize Google mediapipe autoflip solution before using Katna video resize (experimental) feature.

Install Google Mediapipe library and Autoflip solution.

  1. Install Mediapipe by following these instructions : https://google.github.io/mediapipe/getting_started/install
  2. Build Autoflip c++ solution by following these instructions: https://google.github.io/mediapipe/solutions/autoflip

Resize a single video using Katna (Using Experimental Mediapipe Autoflip bridge)

Step 1

Import the video module

from Katna.video import Video

Step 2

Instantiate the video class inside your main module (necessary for multiprocessing in windows)

autoflip_build_path = "/absolute/path/to/autoflip/build/folder
autoflip_model_path = "/absolute/path/to/autoflip/model/folder

if __name__ == "__main__":
     vd = Video(autoflip_build_path, autoflip_model_path)

Step 3 (Optional)

Configure the mediapipe autoflip properties. To check the list of configurable options, check Katna.video_resize module.

import Katna.config as app_config

# get the current configuration
conf = app_config.MediaPipe.AutoFlip.get_conf()

# set True for features which are required in output video
conf["ENFORCE_FEATURES"] = {
     "FACE_CORE_LANDMARKS": False,
     "FACE_ALL_LANDMARKS": False,
     "FACE_FULL": False,
     "HUMAN": False,
     "PET": False,
     "CAR": False,
     "OBJECT": False
}

# % stabalization threshold
conf["STABALIZATION_THRESHOLD"] = 0.5

# opacity of blur area
conf["BLUR_AREA_OPACITY"] = 0.6

# update configuration
app_config.MediaPipe.AutoFlip.set_conf(conf)

Step 4

Call the resize_video method. The method accepts three parameters and returns a status whether video resize is performed successfully or not. Refer to API reference for further details. Below are the four parameters required by the method

  1. file_path: Video file path.
  2. abs_file_path_output: absolute path for saving final output file.
  3. aspect_ratio: required aspect ratio for output video. e.g. “4:3”
vd.resize_video(file_path = file_path, abs_file_path_output = abs_file_path_output, aspect_ratio = aspect_ratio)

Code below is a complete example for a single video file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from Katna.video import Video
import os

# For windows, the below if condition is must.
if __name__ == "__main__":

     # set the autoflip build and model path directory based on your installation
     # usually autoflip build is located here : /mediapipe/repo/bazel-build/mediapipe/examples/desktop/autoflip
     # usually mediapipe model is located here : /mediapipe/repo/mediapipe/models
     autoflip_build_path = "/absolute/path/to/autoflip/build/folder
     autoflip_model_path = "/absolute/path/to/autoflip/model/folder

     # desired aspect ratio (e.g potrait mode - 9:16)
     aspect_ratio = 9:16

     # input video file path
     file_path = os.path.join(".", "tests", "data", "pos_video.mp4")

     # output file to save resized video
     abs_file_path_output = os.path.join(".", "tests", "data", "pos_video_resize.mp4")

     #instantiate the video class
     vd = Video(autoflip_build_path, autoflip_model_path)

     print(f"Input video file path = {file_path}")

     vd.resize_video(file_path = file_path, abs_file_path_output = abs_file_path_output, aspect_ratio = aspect_ratio)

     print(f"output resized video file path = {abs_file_path_output}")

NOTE : In case of subprocess.CalledProcessError, try running the resize_video method again.

Resize multiple videos in a directory using Katna (Using Experimental Mediapipe Autoflip bridge)

Call the resize_video_from_dir method. The method accepts three parameters and returns a status whether video resize is performed successfully or not. Refer to API reference for further details. Below are the four parameters required by the method

  1. dir_path: Directory path where videos are stored.
  2. abs_dir_path_output: absolute path to directory where resized videos will be dumped.
  3. aspect_ratio: required aspect ratio for output video. e.g. “4:3”
vd.resize_video_from_dir(dir_path = dir_path, abs_dir_path_output = abs_dir_path_output, aspect_ratio = aspect_ratio)

Code below is a complete example for a folder full of video file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from Katna.video import Video
import os

# For windows, the below if condition is must.
if __name__ == "__main__":

     # folder where videos are located
     dir_path = file_path = os.path.join(".", "tests", "data")

     # output folder to dump videos after resizing
     abs_dir_path_output = os.path.join(".", "tests", "data", "resize_results")

     # intialize video class
     vd = Video(autoflip_build_path, autoflip_model_path)

     # invoke resize for directory
     try:
          vd.resize_video_from_dir(dir_path = dir_path, abs_dir_path_output = abs_dir_path_output, aspect_ratio = aspect_ratio)
     except Exception as e:
          raise e

     print(f"output resized video dir path = {abs_dir_path_output}")