File size: 3,330 Bytes
5244c19
0ebc3c4
3b6cf03
98acae8
89b6dcb
 
 
98acae8
c6b75bd
98acae8
 
c6b75bd
 
98acae8
5244c19
89b6dcb
 
 
 
 
 
 
c6b75bd
89b6dcb
 
 
 
 
 
 
 
 
 
c6b75bd
89b6dcb
 
 
 
 
c6b75bd
 
 
89b6dcb
c6b75bd
89b6dcb
c6b75bd
 
 
89b6dcb
 
c6b75bd
 
 
89b6dcb
c6b75bd
89b6dcb
 
 
 
3b6cf03
89b6dcb
 
 
3b6cf03
 
 
 
c6b75bd
98acae8
 
3b6cf03
 
 
580dcd1
 
3b6cf03
c6b75bd
580dcd1
c6b75bd
3b6cf03
98acae8
c6b75bd
98acae8
 
 
 
 
 
89b6dcb
 
 
 
 
 
 
98acae8
89b6dcb
 
fa08cd8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import gradio as gr
import os
from moviepy.editor import AudioFileClip, ImageClip
from pathlib import Path
import subprocess
import uuid
import shutil


output_dir = Path("temp/")
output_dir.mkdir(exist_ok=True, parents=True)

os.chdir(output_dir) # change working directory to output_dir because the hf spaces model has no option to specify output directory ¯\_(ツ)_/¯


class SpotifyApi:
    spotify_directory = Path(output_dir / "spotify")
    final_directory = output_dir

    def __init__(self):
        self.setup_spotipy

    def setup_spotipy(self) -> None:
        # Check if the credentials file exists
        if not os.path.exists("spotif.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"])
        else:
            pass

    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) -> str | None:
        # Look in all the subdirectories of spotify for the mp3 file
        for root, dirs, files in os.walk(
            Path(self.spotify_directory / self.foldername)
        ):
            for file in files:
                if file.endswith(".mp3"):
                    final_mp3 = Path(
                        self.final_directory / self.foldername
                    ).with_suffix(".mp3")
                    shutil.rmtree(Path(self.spotify_directory / self.foldername))
                    shutil.copy(os.path.join(root, file), final_mp3)
                    return final_mp3.as_posix()


def process_inputs(prompt, audio, spotify_url):
    image = get_stable_diffusion_image(prompt)
    if spotify_url:
        spotify = SpotifyApi()
        audio = spotify.download_episode(spotify_url)
    video = add_static_image_to_audio(image, audio)
    return video


def add_static_image_to_audio(image, audio) -> str:
    """Create and save a video file to `output_path` after
    combining a static image that is located in `image_path`
    with an audio file in `audio_path`"""
    audio_clip = AudioFileClip(audio)
    image_clip = ImageClip(image)
    video_clip = image_clip.set_audio(audio_clip)
    video_clip.duration = audio_clip.duration
    video_clip.fps = 1
    path = Path(output_dir / "output.mp4")
    video_clip.write_videofile(path)
    return path.as_posix()


def get_stable_diffusion_image(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)][0]


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"),
    ],
    outputs="video",
)


iface.launch()