Rucha Katakwar | 222c531 | 2022-03-21 14:17:01 -0700 | [diff] [blame] | 1 | # Copyright 2022 The Android Open Source Project |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | """Utility functions for processing video recordings. |
| 15 | """ |
| 16 | # Each item in this list corresponds to quality levels defined per |
| 17 | # CamcorderProfile. For Video ITS, we will currently test below qualities |
| 18 | # only if supported by the camera device. |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 19 | import logging |
| 20 | import os.path |
| 21 | import subprocess |
| 22 | import time |
| 23 | |
| 24 | |
Rucha Katakwar | 089e609 | 2022-03-30 11:19:26 -0700 | [diff] [blame] | 25 | ITS_SUPPORTED_QUALITIES = ( |
Rucha Katakwar | 41133f9 | 2022-03-22 13:44:09 -0700 | [diff] [blame] | 26 | 'HIGH', |
| 27 | '2160P', |
| 28 | '1080P', |
| 29 | '720P', |
| 30 | '480P', |
| 31 | 'CIF', |
| 32 | 'QCIF', |
| 33 | 'QVGA', |
| 34 | 'LOW', |
| 35 | 'VGA' |
Rucha Katakwar | 222c531 | 2022-03-21 14:17:01 -0700 | [diff] [blame] | 36 | ) |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 37 | |
| 38 | |
Rucha Katakwar | 932bded | 2022-04-04 14:29:52 -0700 | [diff] [blame^] | 39 | def extract_key_frames_from_video(log_path, video_file_name): |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 40 | """ |
| 41 | Returns a list of extracted key frames. |
| 42 | |
| 43 | Ffmpeg tool is used to extract key frames from the video at path |
Rucha Katakwar | 932bded | 2022-04-04 14:29:52 -0700 | [diff] [blame^] | 44 | os.path.join(log_path, video_file_name). |
| 45 | The extracted key frames will have the name video_file_name with "_key_frame" |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 46 | suffix to identify the frames for video of each quality.Since there can be |
| 47 | multiple key frames, each key frame image will be differentiated with it's |
| 48 | frame index.All the extracted key frames will be available in jpeg format |
| 49 | at the same path as the video file. |
| 50 | |
| 51 | Args: |
| 52 | log_path: path for video file directory |
Rucha Katakwar | 932bded | 2022-04-04 14:29:52 -0700 | [diff] [blame^] | 53 | video_file_name: name of the video file. |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 54 | Ex: VID_20220325_050918_0_CIF_352x288.mp4 |
| 55 | Returns: |
| 56 | key_frame_files: A list of paths for each key frame extracted from the |
| 57 | video. |
| 58 | """ |
Rucha Katakwar | 932bded | 2022-04-04 14:29:52 -0700 | [diff] [blame^] | 59 | ffmpeg_image_name = f"{video_file_name.split('.')[0]}_key_frame" |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 60 | ffmpeg_image_file_path = os.path.join(log_path, ffmpeg_image_name + '_%02d.png') |
| 61 | cmd = ['ffmpeg', |
| 62 | '-skip_frame', |
| 63 | 'nokey', |
| 64 | '-i', |
Rucha Katakwar | 932bded | 2022-04-04 14:29:52 -0700 | [diff] [blame^] | 65 | os.path.join(log_path, video_file_name), |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 66 | '-vsync', |
| 67 | 'vfr', |
| 68 | '-frame_pts', |
| 69 | 'true' , |
| 70 | ffmpeg_image_file_path, |
| 71 | ] |
Rucha Katakwar | 932bded | 2022-04-04 14:29:52 -0700 | [diff] [blame^] | 72 | logging.debug('Extracting key frames from: %s' % video_file_name) |
Rucha Katakwar | b6847db | 2022-03-24 16:49:13 -0700 | [diff] [blame] | 73 | output = subprocess.call(cmd) |
| 74 | arr = os.listdir(os.path.join(log_path)) |
| 75 | key_frame_files = [] |
| 76 | for file in arr: |
| 77 | if '.png' in file and not os.path.isdir(file) and ffmpeg_image_name in file: |
| 78 | key_frame_files.append(file) |
| 79 | return key_frame_files |
| 80 | |
| 81 | |
| 82 | def get_key_frame_to_process(key_frame_files): |
| 83 | """ |
| 84 | Returns the key frame file from the list of key_frame_files. |
| 85 | |
| 86 | If the size of the list is 1 then the file in the list will be returned else |
| 87 | the file with highest frame_index will be returned for further processing. |
| 88 | |
| 89 | Args: |
| 90 | key_frame_files: A list of key frame files. |
| 91 | Returns: |
| 92 | key_frame_file to be used for further processing. |
| 93 | """ |
| 94 | key_frame_files.sort() |
| 95 | return key_frame_files[-1] |