Podfusion / app.py
spookyuser
Works I think
e536326
raw
history blame
4.51 kB
import os
import shutil
import subprocess
import sys
import uuid
from pathlib import Path
import gradio as gr
from moviepy.editor import AudioFileClip
output_dir = Path("temp/").absolute()
output_dir.mkdir(exist_ok=True, parents=True)
class SpotifyApi:
spotify_directory = Path("spotify")
final_directory = output_dir
def __init__(self):
self.setup_spotify()
def setup_spotify(self) -> None:
# Check if the credentials file exists
if not os.path.exists("spotify.rc"):
with open("spotify.rc", "w") as f:
f.write(
f"{os.environ['SPOTIFY_USERNAME']} {os.environ['SPOTIFY_PASSWORD']}"
)
subprocess.call(["spodcast", "-l", "spotify.rc"])
def download_episode(self, episode_url) -> str:
# Generate a 8 character random string
foldername = str(uuid.uuid4())[:8]
out_path = (self.spotify_directory / foldername).resolve()
subprocess.call(["spodcast", "--root-path", out_path, episode_url])
self.foldername = foldername
mp3_path = self.get_final_mp3()
assert mp3_path is not None
return mp3_path
def get_final_mp3(self):
# Look in all the subdirectories of spotify for the mp3 file
for root, dirs, files in os.walk(
Path(self.spotify_directory / self.foldername).resolve()
):
for file in files:
if file.endswith(".mp3"):
final_mp3 = (
Path(self.final_directory / self.foldername)
.with_suffix(".mp3")
.absolute()
)
shutil.copy(os.path.join(root, file), final_mp3)
shutil.rmtree(
Path(self.spotify_directory / self.foldername).absolute()
)
return final_mp3.as_posix()
class AudioInput:
def __init__(self, path: str, start_time: int, run_for: int):
self.path = path
self.start_time = start_time
self.run_for = run_for
def process_inputs(
prompt: str, audio_path: str, spotify_url: str, start_time: int, run_for: int
) -> str:
audio_input = AudioInput(audio_path, start_time, run_for)
if spotify_url:
spotify = SpotifyApi()
audio_input.path = spotify.download_episode(spotify_url)
images = get_stable_diffusion_images(prompt)
video = animate_images(images, audio_input)
return video
def animate_images(image_paths: list[str], audio_input: AudioInput) -> str:
from animate import ( # Only import after git clone and when necessary takes loooong
create_mp4_with_audio,
get_video_frames,
)
# Generate a random folder name and change directories to there
foldername = str(uuid.uuid4())[:8]
vid_output_dir = Path(output_dir / foldername)
vid_output_dir.mkdir(exist_ok=True, parents=True)
audio_clip = AudioFileClip(audio_input.path)
audio_clip = audio_clip.subclip(
audio_input.start_time, audio_input.start_time + audio_input.run_for
)
video_frames, cv2_images = get_video_frames(image_paths, vid_output_dir)
path = Path(vid_output_dir / "output_final.mp4")
return create_mp4_with_audio(
video_frames, cv2_images, audio_clip.duration, audio_clip, path
)
def get_stable_diffusion_images(prompt) -> str:
stable_diffusion = gr.Blocks.load(name="spaces/stabilityai/stable-diffusion")
gallery_dir = stable_diffusion(prompt, fn_index=2)
return [os.path.join(gallery_dir, img) for img in os.listdir(gallery_dir)][:2]
iface = gr.Interface(
fn=process_inputs,
inputs=[
gr.Textbox(label="Describe your podcast clip"),
gr.Audio(type="filepath", label="Upload an mp3"),
gr.Textbox(label="Or Paste a spotify episode link"),
gr.Number(label="Start time (in seconds)"),
gr.Number(label="Run for (in seconds)"),
],
outputs="video",
)
if __name__ == "__main__":
subprocess.call(
[
"git",
"clone",
"https://github.com/google-research/frame-interpolation",
"frame_interpolation",
]
) # install frame_interplation I guess
sys.path.append("frame_interpolation")
# My installs
os.chdir(
output_dir
) # change working directory to output_dir because the hf spaces model has no option to specify output directory ¯\_(ツ)_/¯
iface.launch()