mirror of
https://github.com/Paillat-dev/viralfactory.git
synced 2026-01-02 01:06:19 +00:00
89 lines
3.3 KiB
Python
89 lines
3.3 KiB
Python
|
|
import os
|
||
|
|
import random
|
||
|
|
import shutil
|
||
|
|
import time
|
||
|
|
|
||
|
|
import gradio as gr
|
||
|
|
import moviepy.editor as mp
|
||
|
|
from moviepy.audio.fx.audio_fadein import audio_fadein
|
||
|
|
from moviepy.audio.fx.audio_fadeout import audio_fadeout
|
||
|
|
|
||
|
|
from . import BaseAudioBackgroundEngine
|
||
|
|
|
||
|
|
|
||
|
|
class MusicAudioBackgroundEngine(BaseAudioBackgroundEngine):
|
||
|
|
name = "Music Audio Background Engine"
|
||
|
|
description = "A basic background engine to set the background audio to a music track."
|
||
|
|
num_options = 1
|
||
|
|
|
||
|
|
def __init__(self, options: list[str]):
|
||
|
|
assets = self.get_assets(type="bcg_music")
|
||
|
|
self.background_audio = [asset for asset in assets if asset.data["name"] == options[0]][0]
|
||
|
|
super().__init__()
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def get_options(cls) -> list:
|
||
|
|
assets = cls.get_assets(type="bcg_music")
|
||
|
|
choices = (
|
||
|
|
[asset.data["name"] for asset in assets]
|
||
|
|
if len(assets) > 0
|
||
|
|
else ["No audios available"]
|
||
|
|
)
|
||
|
|
|
||
|
|
return [
|
||
|
|
gr.Dropdown(
|
||
|
|
choices=choices,
|
||
|
|
label="Background Music",
|
||
|
|
value=choices[0] if len(assets) > 0 else "No audios available",
|
||
|
|
type="value",
|
||
|
|
)
|
||
|
|
]
|
||
|
|
|
||
|
|
def get_background(self):
|
||
|
|
background = mp.AudioFileClip(f"{self.background_audio.path}")
|
||
|
|
self.ctx.credits += f"\n{self.background_audio.data['credits']}"
|
||
|
|
# we add fade in and fade out to the audio
|
||
|
|
background: mp.AudioFileClip = background.fx(audio_fadein, 1).fx(audio_fadeout, 1)
|
||
|
|
# loop the audio to match the duration of the video
|
||
|
|
audio_clips = []
|
||
|
|
while sum([clip.duration for clip in audio_clips]) < self.ctx.duration:
|
||
|
|
audio_clips.append(background)
|
||
|
|
# now we cut the audio to match the duration of the video exactly
|
||
|
|
audio: mp.AudioFileClip = mp.concatenate_audioclips(audio_clips)
|
||
|
|
audio: mp.AudioFileClip = audio.subclip(0, self.ctx.duration)
|
||
|
|
# finally we add a new fade OUT only to the audio
|
||
|
|
audio: mp.AudioFileClip = audio.fx(audio_fadeout, 1)
|
||
|
|
# change volume to 0.5
|
||
|
|
audio: mp.AudioFileClip = audio.volumex(0.5)
|
||
|
|
self.ctx.audio.append(audio)
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def get_settings(cls):
|
||
|
|
def add_file(fp: str, name: str, credits: str):
|
||
|
|
if name == "":
|
||
|
|
raise ValueError("Name cannot be empty.")
|
||
|
|
new_fp = f"local/assets/audios/{time.time()}{os.path.splitext(fp)[1]}"
|
||
|
|
shutil.move(fp, new_fp)
|
||
|
|
cls.add_asset(
|
||
|
|
path=new_fp,
|
||
|
|
metadata={"name": name, "credits": credits},
|
||
|
|
type="bcg_music",
|
||
|
|
)
|
||
|
|
gr.Info("Video added successfully.")
|
||
|
|
|
||
|
|
with gr.Column() as add_asset_inputs:
|
||
|
|
add_asset_name = gr.Textbox(label="Name of the audio", value="")
|
||
|
|
add_asset_credits = gr.Textbox(label="Credits", value="")
|
||
|
|
add_asset_input = gr.File(
|
||
|
|
file_count="single",
|
||
|
|
file_types=["audio"],
|
||
|
|
type="filepath",
|
||
|
|
)
|
||
|
|
with gr.Column() as add_asset_button:
|
||
|
|
add_asset_button = gr.Button(value="Add Audio")
|
||
|
|
add_asset_button.click(
|
||
|
|
add_file,
|
||
|
|
inputs=[add_asset_input, add_asset_name, add_asset_credits],
|
||
|
|
outputs=[],
|
||
|
|
)
|