Skip to content

Commit d3573cc

Browse files
authored
Umar/7132 fix thumbnails path (#235)
* added method to get destination prefix and bucket * exclude only mp4 file with exclude_mp4 flag * added handling for thumbnail groups * fixed path issue * fixed param issue in creating a media convert job * Fixed thumbnail destiation, refactored and added FileConfig class for transcding api * added changelog * fixed failing test * Refactored Fileconfig to move into api * refactored to move code in utils and updated redundant docstrings * removed unit test * meeting linters * fixed failing test * renamed param to remove leading underscore * fixed param name in function call * removed extra change
1 parent cf131c4 commit d3573cc

File tree

6 files changed

+271
-55
lines changed

6 files changed

+271
-55
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
For top level release notes, leave all the headers commented out.
6+
-->
7+
8+
<!--
9+
### Removed
10+
11+
- A bullet item for the Removed category.
12+
13+
-->
14+
<!--
15+
### Added
16+
17+
- A bullet item for the Added category.
18+
19+
-->
20+
<!--
21+
### Changed
22+
23+
- A bullet item for the Changed category.
24+
25+
-->
26+
<!--
27+
### Deprecated
28+
29+
- A bullet item for the Deprecated category.
30+
31+
-->
32+
### Fixed
33+
34+
- Fixed thumbnail path in s3
35+
36+
<!--
37+
### Security
38+
39+
- A bullet item for the Security category.
40+
41+
-->

src/transcoding/mitol/transcoding/api.py

Lines changed: 91 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,21 @@
88
from django.conf import settings
99

1010
from mitol.transcoding.constants import GroupSettings
11+
from mitol.transcoding.utils import (
12+
FileConfig,
13+
filter_mp4_groups,
14+
get_output_path,
15+
is_thumbnail_group,
16+
)
1117

1218

1319
def media_convert_job( # noqa: PLR0913
1420
video_source_key: str,
1521
source_prefix: str = settings.VIDEO_S3_UPLOAD_PREFIX,
1622
source_bucket: str = settings.AWS_STORAGE_BUCKET_NAME,
17-
destination_prefix: str = settings.VIDEO_S3_TRANSCODE_PREFIX,
23+
destination_prefix: str = (
24+
settings.VIDEO_S3_TRANSCODE_PREFIX or settings.VIDEO_S3_UPLOAD_PREFIX
25+
),
1826
destination_bucket: str = (
1927
settings.VIDEO_S3_TRANSCODE_BUCKET or settings.AWS_STORAGE_BUCKET_NAME
2028
),
@@ -29,20 +37,48 @@ def media_convert_job( # noqa: PLR0913
2937
source_bucket (str, optional): S3 bucket for the source video.
3038
destination_prefix (str): Prefix for the destination video.
3139
destination_bucket (str): S3 bucket for the transcoded output
32-
group_settings (dict, optional): Settings for output groups. Defaults to None.
40+
group_settings (dict, optional): Settings for output groups.
3341
3442
Returns:
3543
dict: MediaConvert job details.
3644
"""
3745

38-
if group_settings is None:
39-
group_settings = {}
40-
41-
client = boto3.client(
42-
"mediaconvert",
43-
region_name=settings.AWS_REGION,
44-
endpoint_url=settings.VIDEO_S3_TRANSCODE_ENDPOINT,
46+
file_config = FileConfig(
47+
video_source_key,
48+
source_prefix,
49+
source_bucket,
50+
destination_prefix,
51+
destination_bucket,
52+
group_settings,
4553
)
54+
55+
# Make MediaConvert job
56+
job_dict = make_media_convert_job(file_config)
57+
58+
try:
59+
client = boto3.client(
60+
"mediaconvert",
61+
region_name=settings.AWS_REGION,
62+
endpoint_url=settings.VIDEO_S3_TRANSCODE_ENDPOINT,
63+
)
64+
return client.create_job(**job_dict)
65+
66+
except Exception as e:
67+
err_msg = f"Failed to create MediaConvert client: {e}"
68+
raise ValueError(err_msg) from e
69+
70+
71+
def make_media_convert_job(file_config: FileConfig) -> dict:
72+
"""
73+
Create a MediaConvert job config.
74+
75+
Args:
76+
file_config (FileConfig): Configuration for file paths and settings.
77+
78+
Returns:
79+
dict: MediaConvert job details.
80+
"""
81+
4682
with Path(Path.cwd() / settings.TRANSCODE_JOB_TEMPLATE).open(
4783
encoding="utf-8",
4884
) as job_template:
@@ -56,72 +92,80 @@ def media_convert_job( # noqa: PLR0913
5692
f"arn:aws:iam::{settings.AWS_ACCOUNT_ID}:role/{settings.AWS_ROLE_NAME}"
5793
)
5894

59-
if source_prefix:
60-
destination_path = Path(
61-
video_source_key.replace(
62-
source_prefix,
63-
destination_prefix,
64-
)
65-
)
66-
else:
67-
destination_path = Path(destination_prefix, video_source_key)
68-
destination = str(destination_path.parent / destination_path.stem)
95+
file_config.destination = get_destination_path(file_config)
6996

7097
job_dict["Settings"]["Inputs"][0]["FileInput"] = (
71-
f"s3://{source_bucket}/{video_source_key}"
98+
f"s3://{file_config.source_bucket}/{file_config.video_source_key}"
7299
)
73100

74-
add_group_settings(job_dict, destination, destination_bucket, group_settings)
101+
add_group_settings(job_dict, file_config)
75102

76-
return client.create_job(**job_dict)
103+
return job_dict
104+
105+
106+
def get_destination_path(file_config: FileConfig) -> str:
107+
"""
108+
Calculate the destination path for transcoded files.
109+
110+
Args:
111+
file_config (FileConfig): Configuration for file paths and settings.
77112
78113
79-
def add_group_settings(
80-
job_dict: dict,
81-
destination: str,
82-
destination_bucket: str,
83-
group_settings: dict,
84-
) -> None:
114+
Returns:
115+
str: Destination path for the transcoded files.
116+
"""
117+
if file_config.source_prefix:
118+
destination_path = Path(
119+
file_config.video_source_key.replace(
120+
file_config.source_prefix,
121+
file_config.destination_prefix,
122+
)
123+
)
124+
else:
125+
destination_path = Path(
126+
file_config.destination_prefix, file_config.video_source_key
127+
)
128+
129+
return str(destination_path.parent / destination_path.stem)
130+
131+
132+
def add_group_settings(job_dict: dict, file_config: FileConfig) -> None:
85133
"""
86134
Add group settings to the MediaConvert job dictionary.
87135
88136
Args:
89137
job_dict (dict): MediaConvert job dictionary.
90-
destination (str): Destination path for the output files.
91-
group_settings (dict): Group settings for the job.
92-
destination_bucket (str, optional): S3 bucket for the transcoded output.
93-
"""
138+
file_config (FileConfig): Configuration for file paths and settings.
94139
95-
exclude_mp4 = group_settings.get("exclude_mp4", False)
140+
"""
96141
output_groups = job_dict["Settings"]["OutputGroups"]
97142

98-
if exclude_mp4:
99-
# Remove the MP4 output group if not needed
100-
output_groups = [
101-
group
102-
for group in output_groups
103-
if group["OutputGroupSettings"]["Type"] != GroupSettings.FILE_GROUP_SETTINGS
104-
]
105-
job_dict["Settings"]["OutputGroups"] = output_groups
143+
if file_config.group_settings.get("exclude_mp4", False):
144+
filtered_groups = filter_mp4_groups(output_groups)
145+
job_dict["Settings"]["OutputGroups"] = filtered_groups
146+
output_groups = filtered_groups
106147

107148
for group in output_groups:
108149
output_group_settings = group["OutputGroupSettings"]
109-
group_settings_type = group["OutputGroupSettings"]["Type"]
150+
group_settings_type = output_group_settings["Type"]
151+
152+
_is_thumbnail_group = is_thumbnail_group(group)
153+
110154
if group_settings_type == GroupSettings.HLS_GROUP_SETTINGS:
111155
group_settings_key = GroupSettings.HLS_GROUP_SETTINGS_KEY
112156
output_group_settings[group_settings_key]["SegmentLength"] = (
113-
group_settings.get("SegmentLength", 10)
157+
file_config.group_settings.get("SegmentLength", 10)
114158
)
115159
output_group_settings[group_settings_key]["AdditionalManifests"][0][
116160
"ManifestNameModifier"
117-
] = group_settings.get("ManifestNameModifier", "__index")
161+
] = file_config.group_settings.get("ManifestNameModifier", "__index")
118162
elif group_settings_type == GroupSettings.FILE_GROUP_SETTINGS:
119163
group_settings_key = GroupSettings.FILE_GROUP_SETTINGS_KEY
120164
else:
121165
group_type = group_settings_type
122166
error_msg = f"Unsupported group settings type: {group_type}"
123167
raise ValueError(error_msg)
124-
125-
output_group_settings[group_settings_key]["Destination"] = (
126-
f"s3://{destination_bucket}/{destination}"
168+
output_path = get_output_path(
169+
file_config, is_thumbnail_group=_is_thumbnail_group
127170
)
171+
output_group_settings[group_settings_key]["Destination"] = output_path

src/transcoding/mitol/transcoding/settings/job.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,37 @@
55
VIDEO_S3_TRANSCODE_ENDPOINT = get_string(
66
name="VIDEO_S3_TRANSCODE_ENDPOINT",
77
default="aws_mediaconvert_transcodes",
8-
description=("Endpoint to be used for AWS MediaConvert"),
8+
description="Endpoint to be used for AWS MediaConvert",
99
)
1010
VIDEO_TRANSCODE_QUEUE = get_string(
1111
name="VIDEO_TRANSCODE_QUEUE",
1212
default="Default",
13-
description=("Name of MediaConvert queue to use for transcoding"),
13+
description="Name of MediaConvert queue to use for transcoding",
1414
)
1515
VIDEO_S3_TRANSCODE_BUCKET = get_string(
1616
name="VIDEO_S3_TRANSCODE_BUCKET",
1717
default="",
18-
description=("Bucket to be used for transcoding"),
18+
description="Bucket to be used for transcoding",
1919
)
2020
VIDEO_S3_TRANSCODE_PREFIX = get_string(
2121
name="VIDEO_S3_TRANSCODE_PREFIX",
2222
default="",
23-
description=("Prefix for the transcoded video"),
23+
description="Prefix for the transcoded video",
24+
)
25+
VIDEO_S3_THUMBNAIL_BUCKET = get_string(
26+
name="VIDEO_S3_THUMBNAIL_BUCKET",
27+
default="",
28+
description="Bucket to be used for thumbnail generation",
29+
)
30+
VIDEO_S3_THUMBNAIL_PREFIX = get_string(
31+
name="VIDEO_S3_THUMBNAIL_PREFIX",
32+
default="",
33+
description="Prefix for the thumbnail video",
2434
)
2535
VIDEO_S3_UPLOAD_PREFIX = get_string(
2636
name="VIDEO_S3_UPLOAD_PREFIX",
2737
default="",
28-
description=("Prefix for the source video"),
38+
description="Prefix for the source video",
2939
)
3040
POST_TRANSCODE_ACTIONS = get_delimited_list(
3141
name="POST_TRANSCODE_ACTIONS",

0 commit comments

Comments
 (0)