Untitled
unknown
plain_text
3 years ago
11 kB
9
Indexable
def split_by_groups(df):
index_list = list(df.index[df.isnull().all(1)])
groups = []
start_idx = 0
for end_idx in index_list:
group = df[start_idx:end_idx]
groups.append(group)
start_idx = end_idx + 1
groups.append(df[start_idx:])
return groups
def manage_group(group_frame):
group_name = group_frame.iloc[0]["group"]
client = group_frame.iloc[0]["client"]
main_result_dir = "result"
source_dir = f"result/{group_name}"
result_dir_path = f"result/{group_name}_result"
upload_client_path = dbx_upload_result_path + "/" + client
folder_exists = False
files_tree = dbx.files_list_folder(dbx_upload_result_path)
for entry in files_tree.entries:
if entry.name == client and isinstance(entry, dropbox.files.FolderMetadata):
folder_exists = True
break
if not folder_exists:
dbx.files_create_folder_v2(upload_client_path)
if not os.path.exists(source_dir):
os.makedirs(source_dir)
if not os.path.exists(main_result_dir):
os.makedirs(main_result_dir)
if not os.path.exists(result_dir_path):
os.makedirs(result_dir_path)
mashups = []
for index, row in group_frame.iterrows():
local_path = f"{source_dir}/{index}.mp4"
if row["video_source"] == "youtube":
download_video_from_yt(row["youtube_link"], source_dir, f"{index}.mp4")
elif row["video_source"] == "dropbox":
download_video_from_db(row["video_name"], local_path)
else:
logging.critical("invalid source")
return
mp_clip = mpy.VideoFileClip(local_path)
if not pd.isna(row['finish_result']):
path = dbx_path + row['finish_result']
try:
# получаем список файлов и папок в указанной директории
results = dbx.files_list_folder(path)
for entry in results.entries:
if isinstance(entry, dropbox.files.FolderMetadata) and entry.path_display == path:
# папка уже существует, используем ее
print(f"Folder {path} already exists.")
break
else:
# папки в списке нет, создаем новую
dbx.files_create_folder_v2(path)
print(f"Folder {path} has been created.")
except dropbox.exceptions.ApiError as e:
print(f"Error accessing folder {path}: {e}")
upload_client_path = path
#обрезать по длине
if mp_clip.duration < 15:
desired_duration = mp_clip.duration
else:
desired_duration = 15
mp_clip = crop_clip_duration(desired_duration, row['timestamp_left'], row['timestamp_right'], mp_clip)
#выровнять соотношение сторон
aspect_ratio = mp_clip.w / mp_clip.h
desired_ratio = 9 / 16
mp_clip = crop_clip_size(desired_ratio, aspect_ratio, mp_clip)
if row['invert_vertical']:
print(row['invert_vertical'])
mp_clip = mp_clip.fx(mpy.vfx.mirror_x)
if not pd.isna(row['cut_orig_video']):
mp_clip = crop_top_bottom_x(mp_clip, int(row['cut_orig_video']))
if row["music_from_video"]:
audio_clip = mp_clip.audio
else:
local_track_path = f"{source_dir}/track.mp3"
track_path = row["track_name"]
if not os.path.exists(local_track_path):
with open(local_track_path, 'wb') as f:
metadata, res = dbx.files_download(dbx_path + track_path)
f.write(res.content)
audio_clip = AudioFileClip(local_track_path)
if row["origin"]:
local_origin_path = f"{result_dir_path}/origin_{index}.mp4"
if not os.path.exists(local_origin_path):
mp_clip = mp_clip.set_audio(audio_clip)
mp_clip.write_videofile(local_origin_path, **settings)
upload_video_to_dbx(local_path=local_origin_path, dbx_upload_path=upload_client_path+f"/{group_name}_origin{index}.mp4")
if row["subs"]:
color = row["sub_color"] or "white"
make_subs_clip(mp_clip, audio_clip, color, source_dir, result_dir_path, index, dbx_subs_path=row["sub_name"], upload_path=upload_client_path+f"/{group_name}_subs{index}.mp4")
if row["mashup"]:
mashups.append(mp_clip.subclip(0, 5).fx(mpy.vfx.fadein, 2).fx(mpy.vfx.fadeout, 2))
if len(mashups) > 0:
make_mashups(mashups, audio_clip, local_save_path=f"{result_dir_path}/mashup", upload_path=f"{upload_client_path}/{group_name}_mashup")
def make_mashups(clips, audio, local_save_path, upload_path):
# Находим наименьшую ширину и высоту среди всех клипов
min_w = min([clip.size[0] for clip in clips])
min_h = min([clip.size[1] for clip in clips])
# Приводим все клипы к одному размеру
resized_clips = []
for clip in clips:
if clip.size[0] != min_w or clip.size[1] != min_h:
# Если размер клипа не совпадает с минимальным размером,
# то обрезаем или изменяем масштаб
if clip.size[0] > min_w:
clip = clip.crop(x1=(clip.size[0]-min_w)/2, x2=min_w+(clip.size[0]-min_w)/2)
elif clip.size[0] < min_w:
clip = clip.resize(width=min_w)
if clip.size[1] > min_h:
clip = clip.crop(y1=(clip.size[1]-min_h)/2, y2=min_h+(clip.size[1]-min_h)/2)
elif clip.size[1] < min_h:
clip = clip.resize(height=min_h)
resized_clips.append(clip)
#массив всех комбинаций из клипов
perms = permutations(resized_clips)
count = 0
for perm in perms:
order = ''.join([str(resized_clips.index(clip) + 1) for clip in perm])
final_clip = concatenate_videoclips(perm)
final_clip = final_clip.set_audio(audio)
if not os.path.exists(local_save_path):
final_clip.write_videofile(local_save_path + f"_{order}.mp4", **settings)
upload_video_to_dbx(local_path=local_save_path + f"_{order}.mp4", dbx_upload_path=upload_path + f"{order}.mp4")
count = count + 1
def make_subs_clip(clip, audio_clip, color, source_dir, result_dir_path, index, dbx_subs_path, upload_path):
local_sub_path = f"{source_dir}/subs.srt"
local_subs_clip_path = f"{result_dir_path}/subs_{index}.mp4"
if not os.path.exists(local_subs_clip_path):
try:
with open(local_sub_path, 'wb') as f:
metadata, res = dbx.files_download(dbx_path + dbx_subs_path)
f.write(res.content)
sub_clip = make_subs(clip, local_sub_path, color)
sub_clip = sub_clip.set_audio(audio_clip)
sub_clip.write_videofile(local_subs_clip_path, **settings)
upload_video_to_dbx(local_path=local_subs_clip_path, dbx_upload_path=upload_path)
except Exception as e:
logging.critical(f"something went wrong with subtitle file: {e}")
def make_subs(clip, sub_path, color):
font_size = int(min(clip.size[0], clip.size[0]) * 0.05)
generator = lambda txt: TextClip(txt, font='Arial', fontsize=font_size, color=color)
subs = SubtitlesClip(sub_path, generator)
subtitles = SubtitlesClip(subs, generator)
result = CompositeVideoClip([clip, subtitles.set_pos(('center', 'center'))])
return result
def download_video_from_db(path, local_path):
print(path, local_path)
if not os.path.exists(local_path):
try:
with open(local_path, 'wb') as f:
metadata, res = dbx.files_download(dbx_path + path)
f.write(res.content)
except Exception as e:
logging.critical(f"something went wrong: {e}")
def download_video_from_yt(link, group_name, file_name):
yt = YouTube(link)
print(link)
yt.streams.filter(progressive=False, file_extension='webm').order_by('resolution')[-1].download(group_name, filename=file_name)
def upload_video_to_dbx(local_path, dbx_upload_path):
try:
with open(local_path, "rb") as f:
dbx.files_upload(f.read(), dbx_upload_path)
except Exception as e:
logging.critical(f"something went wrong with upload file to dropbox: {e}")
def crop_clip_size(desired_ratio, aspect_ratio, clip):
if aspect_ratio > desired_ratio:
# вырезаем кусок по горизонтали
width = int(clip.size[1] * desired_ratio)
x_center = int((clip.size[0] - width) / 2)
crop_area = (x_center, 0, x_center + width, clip.size[1])
else:
# вырезаем кусок по вертикали
height = int(clip.size[0] / desired_ratio)
y_center = int((clip.size[1] - height) / 2)
crop_area = (0, y_center, clip.size[0], y_center + height)
return clip.crop(*crop_area)
def crop_clip_duration(desired_duration, start, end, clip):
if clip.duration > desired_duration:
if pd.isna(end):
minutes, seconds = start.split(':')
start = int(minutes) * 60 + int(seconds)
end = start + desired_duration
clip = clip.subclip(start, end)
else:
clip = clip.subclip(start, end)
return clip
def crop_top_bottom_x(clip, x):
video_height = clip.size[1]
crop_top = int(video_height * (x / 100))
crop_bottom = int(video_height * (1 - x / 100))
clip = clip.crop(y1=crop_top, y2=crop_bottom)
return clip
def delete_folder(folder_path):
print("deleting")
for process in psutil.process_iter():
try:
for file in process.open_files():
if file.path.startswith(folder_path):
process.kill()
break
except Exception as e:
pass
shutil.rmtree(folder_path, ignore_errors=True)
def main():
groups = split_by_groups(data_table)
for group in groups:
try:
manage_group(group)
except Exception as e:
logging.critical(f"invalid group {group.iloc[0]['group']}: {e}")
#remove_result()
main()
def remove_result():
delete_folder("result")Editor is loading...